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

PHP批量执行20K次CURL请求并导出Excel失败问题求助

处理20K次CURL请求并写入Excel时的崩溃问题

你遇到的情况太典型了——小批量请求能正常跑,但上万级别的批量操作直接崩得悄无声息,连个错误提示都没有。结合你的代码和场景,我整理了几个核心优化方向,应该能解决问题:

1. 修复CURL资源浪费:复用句柄而非频繁创建销毁

你当前的getCurl函数每次请求都新建+关闭CURL句柄,20K次下来会产生巨量的资源开销,很容易把内存耗干。改成复用单个句柄:

// 先在循环外初始化一次CURL句柄
$curl = curl_init();
curl_setopt_array($curl, array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_HTTPHEADER => array(
        "Content-Type: text/xml",
        "cache-control: no-cache"
    ),
));

// 修改getCurl函数,复用已有的句柄
function getCurl($curl, $url, $soapBody) {
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $soapBody);
    
    $response = curl_exec($curl);
    $err = curl_error($curl);
    
    if ($err) {
        error_log("cURL Error #:" . $err); // 用error_log记录,避免echo打断批量流程
        return false;
    } else {
        return $response;
    }
}

// 所有请求结束后再关闭句柄
curl_close($curl);

这一步能大幅减少资源创建销毁的开销,直接降低内存占用峰值。

2. 分批处理,避免一次性加载/写入过量数据

20K条数据一次性堆在内存里很容易撑爆,改成分批写入+内存释放:

$writer->openToFile('products.xlsx');
$batchSize = 1000; // 每1000条做一次刷新
$count = 0;

foreach ($xml->Body->product as $products) {
    $values = [ $products ];
    $rowFromValues = WriterEntityFactory::createRowFromArray($values);
    $writer->addRow($rowFromValues);
    
    $count++;
    // 每达到批次量,手动刷新写入并触发垃圾回收
    if ($count % $batchSize === 0) {
        $writer->flush();
        gc_collect_cycles(); // 手动清理无用内存
    }
}
// 最后一批数据也要记得刷新
$writer->flush();
$writer->close();

分批处理能把内存占用控制在合理范围,不会一次性堆太多数据。

3. 开启错误日志,抓出隐性崩溃原因

页面空白大概率是脚本崩溃但没输出错误,你需要强制记录错误日志:
在脚本开头添加:

error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', './batch_operation.log');

之后所有错误(比如内存耗尽、CURL请求失败细节)都会写入batch_operation.log,能帮你精准定位问题点。

4. 调整PHP内存配置,不止是超时时间

你只设置了超时时间为0,但PHP的内存限制才是常见瓶颈:
在脚本开头添加:

ini_set('memory_limit', '256M'); // 可根据服务器配置调整到512M甚至1G

这是临时缓解方案,核心还是前面的内存优化操作。

5. 精简循环内操作,减少冗余开销

检查循环里有没有重复创建对象或冗余代码,比如确认WriterEntityFactory::createRowFromArray是否可以优化,避免不必要的变量赋值,尽量让循环里的操作保持极简。

建议先从复用CURL句柄和分批处理这两点入手,这是解决这类批量操作崩溃最有效的方法,再配合错误日志排查剩余问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:22:48