当前位置: 首页> 最新文章列表> 如何使用 curl_close 配合 curl_multi_exec 进行批量请求处理?

如何使用 curl_close 配合 curl_multi_exec 进行批量请求处理?

gitbox 2025-05-26

在进行大量 HTTP 请求时,PHP 提供的 curl_multi_exec 是实现并发请求的常用利器。然而,很多开发者在使用它时会忽略一个关键细节:curl_close 的正确使用时机。如果不当使用,不仅会导致资源泄露,还可能造成请求未完成、响应异常等问题。本文将深入讲解如何正确使用 curl_close 函数,配合 curl_multi_exec 实现高效、稳定的批量 HTTP 请求处理。

一、curl_multi_exec 简介

curl_multi_exec 是 PHP CURL 扩展提供的函数之一,它允许我们将多个 curl 请求句柄(handle)添加到一个 curl multi 句柄中,并通过非阻塞的方式并发执行这些请求。相比传统的串行请求,它能显著提升处理效率。

二、常见的错误使用方式

很多开发者在处理完某个请求后,立即调用 curl_close($ch) 释放资源,这是不正确的。在使用 curl_multi_exec 的并发模型中:

$mh = curl_multi_init();
$chs = [];

foreach ($urls as $url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_multi_add_handle($mh, $ch);
    $chs[] = $ch;

    // 错误做法:不要在这里调用 curl_close
    // curl_close($ch);
}

三、正确的使用步骤

正确使用 curl_multi_execcurl_close 的流程如下:

  1. 初始化 multi 句柄;

  2. 创建多个 curl 句柄并设置选项;

  3. 将 curl 句柄添加到 multi 句柄;

  4. 执行请求;

  5. 逐个移除句柄,并调用 curl_close

  6. 关闭 multi 句柄。

下面是一个完整、正确的示例:

$urls = [
    'https://gitbox.net/api/endpoint1',
    'https://gitbox.net/api/endpoint2',
    'https://gitbox.net/api/endpoint3',
];

$mh = curl_multi_init();
$handles = [];
$responses = [];

// 1. 创建并配置每个 curl 句柄
foreach ($urls as $i => $url) {
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_URL => $url,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 10,
    ]);
    curl_multi_add_handle($mh, $ch);
    $handles[$i] = $ch;
}

// 2. 执行并发请求
$running = null;
do {
    $status = curl_multi_exec($mh, $running);
    if ($running) {
        curl_multi_select($mh);
    }
} while ($running && $status == CURLM_OK);

// 3. 读取响应并清理资源
foreach ($handles as $i => $ch) {
    $responses[$i] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
    curl_close($ch); // 正确时机:在 handle 被移除之后再关闭
}

curl_multi_close($mh);

// 可选:处理响应数据
foreach ($responses as $i => $body) {
    echo "Response #$i: " . substr($body, 0, 100) . PHP_EOL;
}

四、关键注意事项

  • 不要提前关闭 curl 句柄。必须确保请求执行完毕并已从 multi handle 中移除之后再调用 curl_close

  • curl_multi_select 是提升性能的关键,它能避免 CPU 空转。

  • 所有句柄都应在最后通过 curl_multi_remove_handlecurl_close 正确释放,否则可能造成内存泄露。

  • 若使用的 URL 域名固定,可以通过统一配置或变量替换方式集中管理,如:

$domain = 'gitbox.net';
$url = "https://{$domain}/api/endpoint";

五、结语

通过正确地管理 curl_multi_execcurl_close 的使用时机,可以极大地提升 PHP 批量 HTTP 请求处理的效率和稳定性。这个流程尤其适用于高并发的数据采集、API 聚合等应用场景,是每个 PHP 开发者值得掌握的技能。