如何用PHP循环打开带参数URL并在每个请求完成后回调更新进度?
PHP实现循环请求带参数URL并实时更新进度
你的代码存在的核心问题
你写的这段代码根本无法实现需求,原因有两点:
- 执行
header("location: ...")后,当前PHP脚本会立即终止,后续的$_SESSION['progress']=$i永远不会被执行 - 每次跳转都会离开当前脚本,根本没法完成1到100的循环请求,每次只能执行一次跳转
仅用PHP可以实现需求,正确方案如下
不需要页面跳转,用PHP的cURL扩展在当前脚本内部发起HTTP请求,同时配合SESSION记录进度,前端用AJAX轮询获取进度即可。
1. 处理请求的核心脚本(process.php)
session_start(); // 初始化进度 if (!isset($_SESSION['progress'])) { $_SESSION['progress'] = 0; } $total = 100; for ($i = 1; $i <= $total; $i++) { // 初始化cURL请求 $ch = curl_init("https://www.hellokitty.com/userupdate.php?id=$i"); // 设置不输出响应内容,只确保请求完成 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 执行请求 curl_exec($ch); // 关闭cURL资源 curl_close($ch); // 更新进度值 $_SESSION['progress'] = $i; // 强制写入SESSION,避免缓存导致AJAX读取延迟 session_write_close(); session_start(); // 可选:添加短暂延迟,避免请求过于频繁触发目标服务器反爬 usleep(50000); // 延迟50毫秒 } // 全部完成后标记状态 $_SESSION['progress'] = 'done'; session_write_close();
2. 前端展示页面(index.php)
<!DOCTYPE html> <html> <head> <title>任务进度</title> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> </head> <body> <div>当前进度:<span id="progress-text">0%</span></div> <button id="start-task">开始执行任务</button> <script> $(function() { let progressInterval; $('#start-task').click(function() { // 禁用按钮防止重复触发 $(this).prop('disabled', true); // 异步发起处理请求,避免页面阻塞 $.get('process.php'); // 每500毫秒轮询一次进度 progressInterval = setInterval(() => { $.get('get_progress.php', function(data) { if (data === 'done') { $('#progress-text').text('100% - 任务完成!'); clearInterval(progressInterval); $('#start-task').prop('disabled', false); // 重置进度,方便下次执行 $.get('reset_progress.php'); } else { const percent = Math.round((data / 100) * 100); $('#progress-text').text(`${percent}%`); } }); }, 500); }); }); </script> </body> </html>
3. 获取进度的脚本(get_progress.php)
session_start(); echo isset($_SESSION['progress']) ? $_SESSION['progress'] : 0;
4. 可选:重置进度的脚本(reset_progress.php)
session_start(); $_SESSION['progress'] = 0; echo 'ok';
注意事项
- 确保你的PHP环境开启了cURL扩展(绝大多数主机默认开启,可通过
phpinfo()查看) - 如果目标URL需要身份验证,要在cURL中添加对应的Cookie或请求头(用
curl_setopt($ch, CURLOPT_COOKIE, 'xxx');设置Cookie) - 控制请求频率,避免短时间内大量请求导致目标服务器封禁你的IP
session_write_close()必须调用,否则SESSION的更新会被缓存到脚本结束,AJAX无法实时获取最新进度
内容的提问来源于stack exchange,提问作者Wilf
相关产品推荐
相关产品推荐

