You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP脚本执行后自动重启:解决分页API请求504超时问题

老哥,手动跑12次脚本确实够折腾的!我给你几个实用的方案,帮你实现脚本自动续跑,彻底解放双手😎

方案1:状态持久化+自动重启(最适合web/CLI混合场景)

核心思路是把当前要处理的页码存到一个文件(或者Redis、数据库)里,脚本每次启动先读这个状态,处理完N页后更新状态,再自动启动下一次脚本运行——这样单次脚本的运行时间被拆分,不会触发服务器504超时。

具体步骤:

  1. 先创建一个状态文件(比如page_state.txt),初始内容写1(表示从第1页开始)。
  2. 改造你的PHP脚本,逻辑如下:
    • 读取状态文件里的起始页码
    • 设置单次脚本处理的页数(比如$pagesPerRun = 2,根据API响应速度调整,确保单次运行不超时)
    • 循环处理这批页码
    • 处理完后计算下一批起始页码,更新状态文件
    • 如果还有未处理的页,就通过shell命令启动下一次脚本运行

代码示例:

<?php
// 状态文件路径,根据你的实际位置调整
$stateFile = __DIR__ . '/page_state.txt';
// 单次处理的页数,按需调整
$pagesPerRun = 2;

// 先获取API的总页数(你需要实现这个函数,请求一次首页拿到总页数)
$totalPages = getTotalPagesFromApi();

// 读取当前起始页码
$startPage = file_exists($stateFile) ? (int)file_get_contents($stateFile) : 1;
if ($startPage === 1) {
    file_put_contents($stateFile, $startPage);
}

// 计算本次处理的结束页码(不超过总页数)
$endPage = min($startPage + $pagesPerRun - 1, $totalPages);

// 批量处理页码
for ($page = $startPage; $page <= $endPage; $page++) {
    echo "正在处理第{$page}页...\n";
    // 替换成你的curl请求逻辑
    $response = fetchApiPage($page);
    // 替换成你的数据处理逻辑(存库/写文件等)
    processResponseData($response);
}

// 准备下一次运行的起始页
$nextStartPage = $endPage + 1;

if ($nextStartPage <= $totalPages) {
    // 更新状态文件
    file_put_contents($stateFile, $nextStartPage);
    // 后台启动下一次脚本运行(注意PHP CLI路径,比如/usr/bin/php)
    exec('php ' . __FILE__ . ' > /dev/null 2>&1 &');
    echo "已调度下一次运行,起始页:{$nextStartPage}\n";
} else {
    // 所有页处理完成,删除状态文件
    unlink($stateFile);
    echo "所有页码处理完成!🎉\n";
}

// 辅助函数示例,按需修改
function getTotalPagesFromApi() {
    $ch = curl_init('https://你的API地址?page=1');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $resp = curl_exec($ch);
    curl_close($ch);
    $data = json_decode($resp, true);
    return $data['total_pages'] ?? 12; // 替换成你API返回的总页数字段
}

function fetchApiPage($page) {
    $ch = curl_init("https://你的API地址?page={$page}");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $resp = curl_exec($ch);
    curl_close($ch);
    return json_decode($resp, true);
}

function processResponseData($data) {
    // 这里写你的数据处理逻辑,比如插入数据库
    // ...
}
?>

注意:如果是在服务器上运行,要确保PHP允许执行shell命令,并且php命令的路径正确(可以用which php查看绝对路径)。> /dev/null 2>&1 &是让脚本在后台运行,不占用当前终端。

方案2:Shell脚本循环调用(适合纯CLI环境)

如果你的服务器允许用命令行运行脚本,这个方案更简单——直接写个shell脚本,循环调用你的PHP脚本,每次传入不同的页码参数。

步骤:

  1. 改造PHP脚本,让它接受命令行参数传入页码:
<?php
// 从命令行获取当前页码($argv[0]是脚本文件名,$argv[1]是第一个参数)
$currentPage = $argv[1] ?? 1;
echo "处理第{$currentPage}页...\n";

// 你的curl请求和数据处理逻辑
// ...
?>
  1. 写一个shell脚本(比如run_api.sh):
#!/bin/bash
# 总页数,根据你的实际情况修改
total_pages=12

# 循环调用PHP脚本
for ((page=1; page<=total_pages; page++))
do
    echo "启动处理第${page}页"
    php 你的脚本文件名.php $page
    # 可选:每次请求后暂停1秒,避免给API造成过大压力
    sleep 1
done

echo "所有页码处理完成!"
  1. 给shell脚本加执行权限:
chmod +x run_api.sh
  1. 运行脚本:
./run_api.sh

这个方案的好处是完全避开web服务器的超时限制,因为CLI模式下PHP默认没有执行时间限制(也可以在PHP脚本里加set_time_limit(0)确保不会超时)。

方案3:消息队列(适合大规模/高可靠性场景)

如果你的数据量极大,或者需要处理失败自动重试的机制,可以用消息队列(比如Redis队列、RabbitMQ)。先把所有要处理的页码加入队列,然后启动多个脚本消费者来处理队列任务。不过这个方案稍微复杂一点,适合有一定架构基础的场景。

额外提醒

  • 加重试机制:给API请求加重试逻辑,比如某一页请求失败(500/超时),重试2-3次,避免单次失败中断整个流程。
  • 日志记录:每处理一页都记录日志(比如写入日志文件),方便后续排查问题。
  • CLI优先:尽量用CLI模式运行脚本,web环境的超时限制很容易触发504,CLI模式更稳定。

内容的提问来源于stack exchange,提问作者Alex Baur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:58:52