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

PHP Curl加载耗时过长求助:战地1战队网站数据获取超时

解决PHP Curl加载慢/超时的问题

看起来你遇到的核心问题是在循环里逐个发起Curl请求——每个请求都要经历TCP握手、发送请求、等待响应的完整流程,队员数量多的话,这些时间叠加起来很容易触发30秒的PHP执行超时。下面给你几个针对性的优化方案,按优先级排序:

1. 优先尝试批量请求(如果API支持)

先去核对你使用的游戏数据API是否支持批量查询多个PSNID。很多这类API允许一次性传入多个ID(比如用逗号分隔),这样只需要发起1次Curl请求就能拿到所有队员的数据,这会把请求耗时压缩到原来的几十分之一。

举个示例(假设API支持批量参数):

// 先收集所有队员的PSNID到数组
$psnIds = [];
$data = $connection->query("SELECT psnid FROM bfplayers");
while($row = mysqli_fetch_assoc($data)){
    $psnIds[] = $row['psnid'];
}

// 转成API要求的批量格式(比如逗号分隔字符串)
$batchPsnIds = implode(',', $psnIds);

// 发起单次批量请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://your-api-domain.com?psnids={$batchPsnIds}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 设置请求超时
$response = curl_exec($ch);
curl_close($ch);

// 解析批量返回的数据,对应到每个队员
$allPlayerData = json_decode($response, true);
// 后续渲染页面的逻辑...

2. 缓存API数据(最有效的长期优化)

队员的游戏数据不会实时高频变化,完全没必要每次用户访问页面都去请求API。你可以把API返回的数据存在自己的数据库里,新增一个last_updated字段,设置合理的更新间隔(比如1小时、6小时),只有当数据超过间隔时才去请求API更新。

示例逻辑:

$data = $connection->query("SELECT * FROM bfplayers");
while($row = mysqli_fetch_assoc($data)){
    $psnid = $row['psnid'];
    $lastUpdated = strtotime($row['last_updated']);
    $now = time();

    // 仅当数据超过1小时未更新时,才请求API
    if($now - $lastUpdated > 3600){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, "https://your-api-domain.com?psnid={$psnid}");
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 单个请求超时时间
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5); // 连接超时时间
        $playerData = curl_exec($ch);
        curl_close($ch);

        // 更新数据库中的数据和更新时间
        if($playerData){
            $stmt = $connection->prepare("UPDATE bfplayers SET data = ?, last_updated = NOW() WHERE psnid = ?");
            $stmt->bind_param("ss", $playerData, $psnid);
            $stmt->execute();
            $stmt->close();
        }
    }

    // 从数据库读取缓存的数据展示
    $displayData = json_decode($row['data'], true);
    // 渲染队员信息的页面逻辑...
}

3. 用Curl多处理并行发起请求

如果API不支持批量查询,那可以用curl_multi_init()并行发起多个请求,而不是串行等待每个请求完成,这样能大幅缩短总耗时。

示例简化代码:

// 收集所有PSNID
$psnIds = [];
$data = $connection->query("SELECT psnid FROM bfplayers");
while($row = mysqli_fetch_assoc($data)){
    $psnIds[] = $row['psnid'];
}

// 初始化Curl多处理句柄
$multiHandle = curl_multi_init();
$curlHandles = [];

// 批量创建Curl请求
foreach($psnIds as $psnid){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "https://your-api-domain.com?psnid={$psnid}");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_FORBID_REUSE, false); // 允许复用连接
    $curlHandles[$psnid] = $ch;
    curl_multi_add_handle($multiHandle, $ch);
}

// 执行所有并行请求
$running = null;
do {
    curl_multi_exec($multiHandle, $running);
    curl_multi_select($multiHandle);
} while ($running > 0);

// 收集每个请求的结果
$playerDataMap = [];
foreach($curlHandles as $psnid => $ch){
    $playerDataMap[$psnid] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}
curl_multi_close($multiHandle);

// 后续用$playerDataMap对应每个队员渲染数据...

4. 临时调整PHP执行时间(治标方案)

如果以上优化都做了还是偶尔超时,可以临时延长PHP的执行时间,但这只是应急手段,优先用前面的方法解决根本问题:

// 在脚本开头设置,比如延长到60秒
set_time_limit(60);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:56:16