在處理大量並發HTTP請求時, curl_multi系列函數是PHP中非常實用的工具。其中, curl_multi_close是收尾階段不可或缺的一步,用來正確釋放由curl_multi_init創建的資源。本文將講解curl_multi_close的正確用法,並提供一個實戰示例,幫助你避免常見的資源洩漏問題。
每當使用curl_multi_init創建一個多句柄(curl multi handle)時,PHP都會分配一塊內存用來管理這個多句柄及其包含的各個請求。即使單個子句柄( curl_init生成的)已經用curl_close關閉,整體的multi handle 依然會佔用系統資源。
如果忘記使用curl_multi_close ,在高並發場景下很容易引起內存洩露,甚至導致程序崩潰。
因此,在完成所有並發請求後,必須調用curl_multi_close來徹底釋放資源。
一般使用curl_multi系列函數的流程如下:
創建multi handle( curl_multi_init )
創建並配置多個單獨的curl handle( curl_init )
將各個curl handle 加入multi handle( curl_multi_add_handle )
執行並監控所有請求( curl_multi_exec和curl_multi_select )
移除單個handle( curl_multi_remove_handle )並關閉( curl_close )
最後關閉multi handle( curl_multi_close )
下面是一個完整示例,展示瞭如何同時請求多個URL,並正確清理所有相關資源:
<?php
// 要並發請求的URL列表
$urls = [
"https://gitbox.net/api/endpoint1",
"https://gitbox.net/api/endpoint2",
"https://gitbox.net/api/endpoint3",
];
// 初始化 multi handle
$multiHandle = curl_multi_init();
$curlHandles = [];
// 初始化每個單獨的 curl handle 並加入 multi handle
foreach ($urls as $key => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[$key] = $ch;
}
// 執行請求
$running = null;
do {
$status = curl_multi_exec($multiHandle, $running);
if ($status > CURLM_OK) {
// 錯誤處理
echo "cURL error: " . curl_multi_strerror($status);
break;
}
// 等待活動連接
curl_multi_select($multiHandle);
} while ($running > 0);
// 收集響應結果
$responses = [];
foreach ($curlHandles as $key => $ch) {
$responses[$key] = curl_multi_getcontent($ch);
// 移除並關閉每個子 handle
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
// 最後關閉 multi handle
curl_multi_close($multiHandle);
// 輸出響應
foreach ($responses as $index => $response) {
echo "Response from URL {$urls[$index]}:" . PHP_EOL;
echo $response . PHP_EOL . PHP_EOL;
}
?>
一定要先移除單個curl handle ,再關閉它們,最後關閉multi handle。
不要直接關閉multi handle 後再操作子handle ,那樣會引發不可預期的錯誤。
在高並發環境下建議加上超時控制( CURLOPT_TIMEOUT ),防止長時間阻塞。
curl_multi_close是保證資源合理釋放的最後一步,尤其在多並發場景下,養成良好的關閉習慣非常關鍵。正確地清理每個子句柄並最終關閉multi handle,能有效防止資源洩漏,提高PHP應用的穩定性和性能。