當前位置: 首頁> 最新文章列表> 如何使用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 程序運行得更穩定、更高效。