PHP实现嵌套循环:待服务器有可用槽位时再继续上传数据
解决服务器槽位限制的分批上传问题
针对你的需求,完全可以通过在循环中等待服务器释放可用槽位再继续上传来解决。核心思路是:在每次发送数据前,循环检查服务器剩余槽位,直到有可用槽位时再执行上传操作,同时加入合理的等待时间避免频繁请求服务器。
以下是修改后的完整脚本,附带关键逻辑说明:
$txtfile = 'data.txt'; // 包含上千行数据的文件 $fileData = function() use ($txtfile) { // 逐行读取文件的生成器函数 $file = fopen($txtfile, 'r'); if (!$file) die('文件不存在或无法打开'); while (($line = fgets($file)) !== false) { yield trim($line); // 去除行尾换行符,避免数据携带多余格式 } fclose($file); }; // 封装获取服务器可用槽位的函数,便于复用和维护 function getAvailableSlots() { $response = file_get_contents('https://someserver.com/api/current_slots/'); // 假设API返回纯数字格式的剩余槽位;若返回JSON,需用json_decode解析 if ($response === false) { // 请求失败时默认返回0,暂停上传避免无效请求 return 0; } return (int)$response; } foreach ($fileData() as $line) { // 循环等待,直到服务器有可用槽位 do { $availableSlots = getAvailableSlots(); if ($availableSlots <= 0) { // 无可用槽位时等待3秒,再重新检查 sleep(3); } } while ($availableSlots <= 0); // 对数据做URL编码,避免特殊字符导致请求失败 $encodedData = urlencode($line); $remote_upload_api = "https://someserver.com/api/upload?data={$encodedData}"; $send_data = file_get_contents($remote_upload_api); // 可选:处理上传结果,比如记录失败日志 if ($send_data === false) { error_log("上传失败:{$line}"); } // 可选:上传后短暂等待,给服务器留处理时间 sleep(1); }
关键逻辑说明
- 槽位检查循环:使用
do-while确保至少检查一次槽位,若槽位不足则持续等待,直到有可用资源再执行上传。 - 函数封装:将获取槽位的逻辑封装成独立函数,代码更清晰,后续修改API地址或解析规则时更方便。
- 数据编码:添加
urlencode处理上传数据,避免特殊字符(如空格、&等)破坏请求格式。 - 错误处理:针对获取槽位失败、上传失败的情况做基础处理,避免程序直接崩溃。
- 等待策略:两处
sleep分别用于槽位不足时的等待,以及上传后的缓冲,降低服务器请求压力。
优化建议
- JSON格式适配:如果服务器API返回JSON格式的槽位数据,修改
getAvailableSlots函数的解析逻辑:function getAvailableSlots() { $response = file_get_contents('https://someserver.com/api/current_slots/'); if ($response === false) return 0; $slotData = json_decode($response, true); return isset($slotData['available']) ? (int)$slotData['available'] : 0; } - 超时保护:添加最大等待时间,避免无限等待:
$maxWait = 300; // 最大等待5分钟 $waitStart = time(); do { $availableSlots = getAvailableSlots(); if ($availableSlots <= 0) { if (time() - $waitStart > $maxWait) { die('等待可用槽位超时,程序终止'); } sleep(3); } } while ($availableSlots <= 0); - 改用CURL:
file_get_contents功能有限,使用CURL可自定义超时、请求头,错误处理更灵活:function sendData($data) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://someserver.com/api/upload?data=" . urlencode($data)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $response = curl_exec($ch); curl_close($ch); return $response; } - 批量上传:若服务器支持批量上传接口,可根据剩余槽位数量一次性上传多条数据,大幅提升效率。
内容的提问来源于stack exchange,提问作者Foreseen winx club Gator winx
相关产品推荐
相关产品推荐

