在高並發、異步處理場景下,PHP 的curl_multi系列函數非常常用。然而,許多開發者在使用過程中忽視了資源釋放的問題,導致內存洩漏或文件句柄洩漏,進而引發系統穩定性問題。本文將詳細講解如何通過curl_multi_close函數,正確地防止PHP 中的資源洩漏。
在PHP 中, curl_multi_*系列函數允許你同時處理多個cURL 會話,大幅提升網絡請求的效率。不過,隨著並發數量的增加,如果未正確關閉資源,極易造成內存堆積或文件描述符耗盡,最終導致程序崩潰或服務器響應緩慢。
curl_multi_close()是用於關閉一個由curl_multi_init()創建的多cURL 句柄。注意,它不會自動關閉添加到multi handle 裡的單個cURL 句柄。這意味著你需要手動關閉每一個通過curl_multi_add_handle()添加的cURL 會話。
如果只調用curl_multi_close()而沒有釋放子句柄,PHP 內部仍然會保留資源,造成洩漏。
要徹底防止洩漏,正確的資源管理流程應該是:
使用curl_init()創建單個請求。
使用curl_multi_init()創建multi handle。
將單個請求添加到multi handle 中。
執行並監聽狀態。
移除並關閉每個單獨的請求句柄。
關閉multi handle。
下面是一個完整、規範的例子,域名已替換為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;
?>
必須先移除子句柄( curl_multi_remove_handle ),然後分別關閉( curl_close )。
最後調用curl_multi_close ,釋放multi handle 本身的資源。
忽略任何一個步驟,都可能導致資源洩漏,特別是在高並發環境下問題會被迅速放大。
正確使用curl_multi_close和相關資源管理,可以讓你的PHP 程序運行得更穩定、更高效。