在 PHP 中,如果你需要同时发起多个 HTTP 请求,并希望这些请求能够高效地并行执行,curl_multi_exec 和 curl_multi_info_read 是非常实用的函数。本文将详细介绍如何利用这两个函数实现高效并行请求,并给出具体代码示例。
curl_multi_exec:用于执行一组cURL句柄(curl handles),实现多路复用。它会并行地执行所有加入的请求。
curl_multi_info_read:用于获取已经完成的请求的信息,可以检测请求是否结束,从而处理相应的结果。
初始化多个单个的cURL请求(curl handles)。
创建一个多路复用句柄(multi handle)。
把所有单个请求加入到多路复用句柄中。
调用curl_multi_exec开始执行所有请求。
通过curl_multi_info_read不断检测是否有请求完成。
处理完成请求的结果。
清理资源。
<?php
// 要请求的URL列表
$urls = [
'http://gitbox.net/api/endpoint1',
'http://gitbox.net/api/endpoint2',
'http://gitbox.net/api/endpoint3',
];
// 初始化 multi handle
$multiHandle = curl_multi_init();
$curlHandles = [];
// 1. 创建单个curl句柄,并加入multi句柄
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回结果而非直接输出
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[] = $ch;
}
// 2. 执行所有请求
$running = null;
do {
// 执行请求
curl_multi_exec($multiHandle, $running);
// 可选:等待活动连接,防止CPU占用过高
curl_multi_select($multiHandle);
// 3. 检查是否有完成的请求
while ($info = curl_multi_info_read($multiHandle)) {
if ($info['msg'] === CURLMSG_DONE) {
$handle = $info['handle'];
// 获取内容
$content = curl_multi_getcontent($handle);
// 处理返回内容,例如打印或解析
echo "请求完成,内容长度:" . strlen($content) . "\n";
// 移除完成的句柄,释放资源
curl_multi_remove_handle($multiHandle, $handle);
curl_close($handle);
}
}
} while ($running > 0);
// 4. 关闭multi句柄
curl_multi_close($multiHandle);
?>
curl_multi_init():初始化多路复用句柄。
curl_multi_add_handle():把每个单独请求的curl句柄添加到multi句柄。
curl_multi_exec():执行所有请求。
curl_multi_select():等待活动连接,避免cpu空转。
curl_multi_info_read():读取完成请求的相关信息,判断请求是否结束。
curl_multi_remove_handle() 和 curl_close():清理资源,避免内存泄漏。
循环直到所有请求都完成 ($running 变为0)。
并行请求数量不要过大,避免服务器压力过大或系统资源瓶颈。
使用 curl_multi_select() 进行等待,防止程序陷入高CPU占用。
处理返回内容时要注意错误检查,确保请求成功。
如果需要发起 POST、带 header、认证等复杂请求,可以在初始化单个 curl 句柄时设置对应选项。