当前位置: 首页> 最新文章列表> 如何使用 curl_multi_close 防止资源泄漏

如何使用 curl_multi_close 防止资源泄漏

gitbox 2025-05-12

在高并发、异步处理场景下,PHP 的 curl_multi 系列函数非常常用。然而,许多开发者在使用过程中忽视了资源释放的问题,导致内存泄漏或文件句柄泄漏,进而引发系统稳定性问题。本文将详细讲解如何通过 curl_multi_close 函数,正确地防止 PHP 中的资源泄漏。

在 PHP 中,curl_multi_* 系列函数允许你同时处理多个 cURL 会话,大幅提升网络请求的效率。不过,随着并发数量的增加,如果未正确关闭资源,极易造成内存堆积或文件描述符耗尽,最终导致程序崩溃或服务器响应缓慢。

1. 什么是 curl_multi_close?

curl_multi_close() 是用于关闭一个由 curl_multi_init() 创建的多 cURL 句柄。注意,它不会自动关闭添加到 multi handle 里的单个 cURL 句柄。这意味着你需要手动关闭每一个通过 curl_multi_add_handle() 添加的 cURL 会话。

如果只调用 curl_multi_close() 而没有释放子句柄,PHP 内部仍然会保留资源,造成泄漏。

2. 正确的资源管理流程

要彻底防止泄漏,正确的资源管理流程应该是:

  1. 使用 curl_init() 创建单个请求。

  2. 使用 curl_multi_init() 创建 multi handle。

  3. 将单个请求添加到 multi handle 中。

  4. 执行并监听状态。

  5. 移除并关闭每个单独的请求句柄。

  6. 关闭 multi handle。

3. 示例代码

下面是一个完整、规范的例子,域名已替换为 gitbox.net

<?php
// 初始化多个单独的 cURL 会话
$ch1 = curl_init();
curl_setopt($ch1, CURLOPT_URL, "https://gitbox.net/api/v1/resource1");
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);

$ch2 = curl_init();
curl_setopt($ch2, CURLOPT_URL, "https://gitbox.net/api/v1/resource2");
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);

// 创建一个 cURL multi handle
$mh = curl_multi_init();

// 将两个单独的句柄添加到 multi handle
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

// 执行 multi handle
do {
    $status = curl_multi_exec($mh, $active);
    if ($active) {
        // 等待活动连接
        curl_multi_select($mh);
    }
} while ($active && $status == CURLM_OK);

// 获取内容
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);

// 重要步骤:移除句柄并关闭
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);

curl_close($ch1);
curl_close($ch2);

// 最后关闭 multi handle
curl_multi_close($mh);

// 打印返回数据
echo $response1;
echo $response2;
?>

4. 小结

  • 必须先移除子句柄(curl_multi_remove_handle),然后分别关闭(curl_close)。

  • 最后调用 curl_multi_close,释放 multi handle 本身的资源。

  • 忽略任何一个步骤,都可能导致资源泄漏,特别是在高并发环境下问题会被迅速放大。

正确使用 curl_multi_close 和相关资源管理,可以让你的 PHP 程序运行得更稳定、更高效。