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

如何优化CURL循环300次发送数据的耗时?

嘿,这个场景我太熟悉了——每次循环都新建、销毁CURL句柄,光是TCP连接的建立断开+句柄初始化就会吃掉不少时间,300次下来确实会慢得让人头疼。下面给你两个实用的优化方案,完全不改动原有业务逻辑,就能大幅压缩耗时:

方案一:复用单个CURL句柄(最简单高效的串行优化)

把CURL的初始化和关闭移到循环外面,循环里只更新每次请求需要变化的参数(比如POST数据、动态URL),这样就能避免重复创建销毁句柄的开销,还能复用TCP连接(开启keep-alive的话效果更明显)。

示例代码:

// 只初始化一次CURL句柄,放在循环外
$ch = curl_init();

// 设置那些所有请求都不变的选项
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_URL, "http://website.com");
// 开启TCP长连接,进一步减少连接开销
curl_setopt($ch, CURLOPT_TCP_KEEPALIVE, 1);
curl_setopt($ch, CURLOPT_TCP_KEEPIDLE, 60);
curl_setopt($ch, CURLOPT_TCP_KEEPINTVL, 60);

$users = array_fill(0, 300, 'sample_user'); // 模拟你的300条用户数据
for ($i=0; $i < count($users); $i++){
    // 你的无关代码:比如准备当前请求要发送的数据
    $requestData = [
        'user_id' => $i,
        'user_name' => $users[$i]
    ];
    
    // 仅更新每次请求需要变化的选项(比如POST数据)
    curl_setopt($ch, CURLOPT_POSTFIELDS, $requestData);
    
    // 执行请求(和你原来的逻辑完全一致)
    $response = curl_exec($ch);
    
    // 处理响应:和你原来循环里的处理代码一样
    // ...
}

// 循环结束后再关闭句柄
curl_close($ch);

方案二:使用CURL批量请求(并行执行,速度翻倍)

如果你的API没有严格的请求频率限制,可以用curl_multi把多个请求并行发送,这样300次请求的耗时会接近单次请求的时间(当然要考虑服务器端的并发处理能力)。

示例代码:

$users = array_fill(0, 300, 'sample_user');
$multiHandle = curl_multi_init();
$singleHandles = [];

// 先批量创建单个CURL句柄并加入批量句柄
foreach ($users as $index => $user) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "http://website.com");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    
    // 设置当前请求的动态参数
    $requestData = [
        'user_id' => $index,
        'user_name' => $user
    ];
    curl_setopt($ch, CURLOPT_POSTFIELDS, $requestData);
    
    curl_multi_add_handle($multiHandle, $ch);
    $singleHandles[$index] = $ch;
}

// 执行批量请求
$runningCount = null;
do {
    curl_multi_exec($multiHandle, $runningCount);
    curl_multi_select($multiHandle); // 等待请求完成,避免CPU空转
} while ($runningCount > 0);

// 逐个处理响应(和原来的逻辑一致)
foreach ($singleHandles as $index => $ch) {
    $response = curl_multi_getcontent($ch);
    // 处理当前请求的响应,和你原来循环里的代码一样
    // ...
    
    // 清理单个句柄
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}

// 关闭批量句柄
curl_multi_close($multiHandle);

小提示

  • 如果API有请求频率限制,方案二可以改成分批次并行,比如每次处理20个请求,循环15次,既提升速度又不会触发限流。
  • 两种方案都完全保留了你原来的业务逻辑,只是改变了CURL的执行方式,不用担心功能受影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:53:57