php - PHP - 异步 foreach 循环
问题描述
我有一个分离音乐曲目的网站,但要这样做,用户应该在订阅中购买积分。
我的问题是,例如,当用户从订阅中剩下 2 个学分并上传 3 个曲目时,我的脚本循环遍历这些曲目并看到有有效的学分并立即启动所有这些学分,并将用户可用学分移动到负数.
我需要异步遍历循环,以便每个轨道有机会在通过下一个轨道之前扣除必要的学分,并且它认为它仍然有学分。
下面是我的完整脚本,我添加了一些评论来解释正在发生的事情:
// i first query my db for tracks that are valid and loop through them
$status = 'validated';
$stmt = $conn->prepare("SELECT * FROM demixer.tracks WHERE status=:status");
$stmt->bindParam(':status', $status);
$stmt->execute();
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt->fetchAll() as $row){
$track_id = $row['id'];
echo $track_id.' '.$status.'<br>';
$account_id = $row['account_id'];
$length = $row['length'];
$separation_type = $row['separation_type'];
$separation_algorithm = $row['separation_algorithm'];
$upload_id = $row['upload_id'];
$timings = unserialize($row['timings']);
$length_in_minutes = $length/60;
if($separation_type == 'trial' || $separation_type == 'preview'){
// if the track is a trial i don't have an issue because it doesn't take any credits
}else{
$sub_array = [];
$valid_sub_array = [];
$now = date("Y-m-d H:i:s");
// i get an array of valid subscriptions
$stmt = $conn->prepare("SELECT * FROM demixer.subscriptions WHERE account_id=:account_id AND date_expires>:now");
$stmt->bindParam(':account_id', $account_id);
$stmt->bindParam(':now', $now);
$stmt->execute();
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt->fetchAll() as $key=>$row){
$sub_array[$key] = $row;
}
//if its empty i don't have an issue
if(!empty($sub_array)){
$i = 0;
foreach($sub_array as $row){
$subscription_id = $row['id'];
$no_songs = $row['no_songs'];
$no_minutes = $row['no_minutes'];
$date_expires = $row['date_expires'];
//each subscription has credits for X amount of songs (no_songs) and up to Y length in minutes (no_minutes), when a credit from a subscription is used it is added to the 'subscriptions_used' table in my db, this is the part that needs to be done before looping through to the next track otherwise the credits have not been taken away yet
$stmt = $conn->prepare("SELECT COUNT(*) FROM demixer.subscriptions_used WHERE subscription_id=:subscription_id");
$stmt->bindParam(':subscription_id', $subscription_id);
$stmt->execute();
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
foreach($stmt->fetchAll() as $row){
$no_used = $row['COUNT(*)'];
}
if($no_songs>$no_used){
if($length_in_minutes<$no_minutes){
echo 'this subscription has credits<br />';
$valid_sub_array[$i]['sub_id'] = $subscription_id;
$valid_sub_array[$i]['no_minutes'] = $no_minutes;
$valid_sub_array[$i]['date_expires'] = $date_expires;
$i++;
}else{
$message = 'Demixer only supports tracks up to 10 minutes (600 seconds), please try again with a shorter track';
$status = 'error';
$stmt = $conn->prepare("UPDATE demixer.tracks SET status=:status, message=:message WHERE id=:track_id");
$stmt->bindParam(':status', $status);
$stmt->bindParam(':message', $message);
$stmt->bindParam(':track_id', $track_id);
$stmt->execute();
}
}else{
$message = 'You need to buy more credits';
$status = 'error';
$stmt = $conn->prepare("UPDATE demixer.tracks SET status=:status, message=:message WHERE id=:track_id");
$stmt->bindParam(':status', $status);
$stmt->bindParam(':message', $message);
$stmt->bindParam(':track_id', $track_id);
$stmt->execute();
}
}
}else{
$message = 'You need to buy more credits';
$status = 'error';
$stmt = $conn->prepare("UPDATE demixer.tracks SET status=:status, message=:message WHERE id=:track_id");
$stmt->bindParam(':status', $status);
$stmt->bindParam(':message', $message);
$stmt->bindParam(':track_id', $track_id);
$stmt->execute();
}
array_multisort(array_column($valid_sub_array, 'no_minutes'), SORT_ASC, array_column($valid_sub_array, 'date_expires'), SORT_ASC, $valid_sub_array);
var_dump($valid_sub_array);
if(!empty($valid_sub_array)){
$subscription_to_use = $valid_sub_array[0]['sub_id'];
$stmt = $conn->prepare("INSERT INTO demixer.subscriptions_used (track_id, subscription_id) VALUES (:track_id, :subscription_id)");
$stmt->bindParam(':track_id', $track_id);
$stmt->bindParam(':subscription_id', $subscription_id);
$stmt->execute();
echo 'start full<br />';
$data = array(
'separationAlgorithm' => $separation_algorithm,
'uploadId' => $upload_id,
'outputFormats' => array('mp3')
);
$payload = json_encode($data);
$request = curl_init($api_url.'separation/start');
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($request, CURLOPT_POSTFIELDS, $payload);
curl_setopt($request, CURLOPT_HTTPHEADER, array('Content-Type:application/json','Authorization:'.$token));
curl_setopt($request, CURLOPT_CUSTOMREQUEST, "PUT");
$response = curl_exec($request);
$errors = curl_error($request);
$httpcode = curl_getinfo($request, CURLINFO_HTTP_CODE);
curl_close($request);
if(!empty($errors)){
echo $httpcode.' '.$errors;
}else{
echo $httpcode.' '.$response;
}
echo '<br />';
$decoded_response = (array)json_decode($response);
$separation_id = $decoded_response['separationId'];
$start_separation = date(DATE_RFC822);
$timings['start_separation'] = $start_separation;
$timings = serialize($timings);
$status = 'processing';
$stmt = $conn->prepare("UPDATE demixer.tracks SET status=:status, separation_id=:separation_id, timings=:timings WHERE id=:track_id");
$stmt->bindParam(':status', $status);
$stmt->bindParam(':separation_id', $separation_id);
$stmt->bindParam(':timings', $timings);
$stmt->bindParam(':track_id', $track_id);
$stmt->execute();
}
}
}
解决方案
推荐阅读
- reactjs - 如何在 Typescript 中设置 react-resize-detector 的 HOC?
- string - 如何将一串数据解析为键值对并将其附加到“put”方法中?
- html - 我应该使用 Nginx html 应用程序或/和负载平衡什么?
- python - 使用来自不同线程的 getter 和 setter 访问类时是否需要锁?
- java - org.springframework.web.client.HttpClientErrorException$BadRequest: 400 错误请求
- eclipse - 为什么尝试导出插件片段“找不到导出的单元”?
- python - 最长元音子串 - Python
- amp-html - 如何使用 amp-img 绑定点击事件
- powershell - 有没有办法在输入对象通过管道后访问它?
- javascript - Materialize CSS Dropdown 更新 DOM innerText