在PHP 中,cURL 是一個強大的庫,用於執行網絡請求,如訪問REST API 或抓取網頁。處理單個cURL 請求時,使用curl_init()初始化句柄, curl_exec()執行請求,最後通過curl_close()釋放資源是標準流程。但在處理多個並發請求,特別是使用curl_multi_*系列函數時,正確關閉和清理資源顯得尤為重要。否則可能導致內存洩漏或網絡連接問題。
在單個請求中,典型代碼如下:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gitbox.net/api/data');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch); // 正確釋放資源
這裡, curl_close($ch)是必須的。它會關閉由curl_init()創建的cURL 句柄,並釋放相關資源。
對於需要同時發起多個請求的場景,PHP 提供了curl_multi_*接口。示例如下:
$urls = [
'https://gitbox.net/api/one',
'https://gitbox.net/api/two',
'https://gitbox.net/api/three',
];
$multiHandle = curl_multi_init();
$curlHandles = [];
foreach ($urls as $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[] = $ch;
}
// 執行所有請求
$running = null;
do {
curl_multi_exec($multiHandle, $running);
curl_multi_select($multiHandle);
} while ($running > 0);
// 獲取結果
$responses = [];
foreach ($curlHandles as $ch) {
$responses[] = curl_multi_getcontent($ch);
}
此時,如果你沒有執行下一步的curl_multi_remove_handle和curl_close ,就會出現資源未釋放的問題。
在執行完所有請求並獲取響應後,必須對每個句柄進行清理:
foreach ($curlHandles as $ch) {
curl_multi_remove_handle($multiHandle, $ch); // 從 multi handle 中移除
curl_close($ch); // 關閉單個 cURL 句柄,釋放資源
}
curl_multi_close($multiHandle); // 最後關閉 multi handle
這是確保所有資源都得到釋放的關鍵步驟。僅關閉curl_multi_close()而不逐個調用curl_close()是不夠的。
始終顯式釋放:無論是單個還是多個請求,始終記得用curl_close() 。
使用try-finally 或error handling :處理過程中可能會有異常,建議使用try-finally結構確保句柄最終被釋放。
監控內存和連接數:在高並發環境中,未釋放的cURL 句柄會迅速導致資源耗盡。
封裝請求邏輯:建議封裝成函數或類,在內部處理資源釋放,避免遺漏。
curl_close()在PHP 中並非可有可無,尤其是在多個請求場景下。正確使用curl_multi_remove_handle()和curl_close() ,能確保系統穩定性和性能。寫完請求邏輯後,別忘了這一步:及時清理資源,就是最好的性能優化。