当你需要并发执行多个 cURL 请求时,可以使用 curl_multi_exec() 函数。这个函数允许同时运行多个 cURL 会话,并且通过一个多句柄来管理它们。
以下是一个基本的示例,展示了如何使用 curl_multi_exec() 来处理多个 cURL 请求:
<?php
// 创建多个 cURL 句柄
$ch1 = curl_init("https://gitbox.net/api/data1");
$ch2 = curl_init("https://gitbox.net/api/data2");
$ch3 = curl_init("https://gitbox.net/api/data3");
// 创建一个 cURL 多句柄
$multi_handle = curl_multi_init();
// 将单个 cURL 句柄加入到多句柄中
curl_multi_add_handle($multi_handle, $ch1);
curl_multi_add_handle($multi_handle, $ch2);
curl_multi_add_handle($multi_handle, $ch3);
// 执行多个 cURL 请求
$running = null;
do {
curl_multi_exec($multi_handle, $running);
} while ($running > 0);
// 关闭每个单独的 cURL 句柄
curl_multi_remove_handle($multi_handle, $ch1);
curl_multi_remove_handle($multi_handle, $ch2);
curl_multi_remove_handle($multi_handle, $ch3);
// 关闭多句柄
curl_multi_close($multi_handle);
在这个例子中,我们创建了三个 cURL 请求句柄,并通过 curl_multi_exec() 同时执行它们。注意,虽然 curl_multi_exec() 能同时执行多个请求,但我们仍然需要使用 curl_multi_remove_handle() 和 curl_multi_close() 来确保正确地释放资源。
每次执行完 cURL 请求后,都应该使用 curl_close() 函数释放相应的资源。尽管 curl_multi_close() 会关闭整个多句柄的连接,但它不会自动关闭单独的 cURL 句柄。因此,在完成多任务操作之后,我们必须手动关闭每个 cURL 句柄。若没有正确释放这些资源,可能会导致内存泄漏。
下面是改进后的代码,它正确地使用 curl_close() 来释放每个 cURL 句柄的资源:
<?php
// 创建多个 cURL 句柄
$ch1 = curl_init("https://gitbox.net/api/data1");
$ch2 = curl_init("https://gitbox.net/api/data2");
$ch3 = curl_init("https://gitbox.net/api/data3");
// 创建一个 cURL 多句柄
$multi_handle = curl_multi_init();
// 将单个 cURL 句柄加入到多句柄中
curl_multi_add_handle($multi_handle, $ch1);
curl_multi_add_handle($multi_handle, $ch2);
curl_multi_add_handle($multi_handle, $ch3);
// 执行多个 cURL 请求
$running = null;
do {
curl_multi_exec($multi_handle, $running);
} while ($running > 0);
// 关闭每个单独的 cURL 句柄
curl_close($ch1);
curl_close($ch2);
curl_close($ch3);
// 关闭多句柄
curl_multi_close($multi_handle);
通过这种方式,我们确保了每个 cURL 请求结束后,相关的资源都能被及时释放。
及时释放资源:在所有 cURL 请求完成后,务必调用 curl_close() 来释放每个单独的 cURL 资源,并在最后关闭多句柄。
适当的错误处理:在实际项目中,网络请求可能会失败,导致一些 cURL 句柄没有被正确关闭。可以通过添加错误处理机制来确保无论请求成功与否,资源都能够被释放。例如:
if ($ch1) {
// 如果请求成功,关闭 cURL 资源
curl_close($ch1);
}
监控内存使用情况:在处理多个并发 cURL 请求时,可以通过监控 PHP 的内存使用情况,确保不会发生内存泄漏。在一些复杂的应用中,适时地使用 gc_collect_cycles() 来强制回收 PHP 的内存垃圾,也能帮助减少内存占用。
限制并发请求的数量:尽管 curl_multi_exec() 可以同时执行多个请求,但过多的并发请求可能会导致系统资源的过度占用。在实际应用中,可以通过适当限制并发请求的数量,避免过多的 cURL 请求占用过多内存。