在PHP中, cURL是一個強大且常用的網絡請求工具,而curl_multi_*系列函數允許我們。這在進行高性能接口聚合、異步請求等場景中非常有用。
然而,許多開發者在使用curl_multi_*時,常常忽略了資源的釋放環節,尤其是curl_multi_close()的使用。本文將以標準流程為主線,帶你一步步理解從curl_multi_init到curl_multi_close的完整使用方式,並輔以代碼示例說明。
PHP 提供的curl_multi_*系列函數是用於管理多個並發curl 句柄的工具。這與傳統的單個curl 請求不同,它允許你同時發起多個HTTP 請求,提升響應效率。
使用這些函數可以大致分為以下幾個步驟:
初始化multi 句柄: curl_multi_init()
添加多個curl 請求(easy handle): curl_multi_add_handle()
獲取響應內容: curl_multi_getcontent()
移除並關閉easy handle: curl_multi_remove_handle()和curl_close()
關閉multi handle: curl_multi_close()
下面是一個標準的多請求流程,假設我們需要並發請求三個不同的URL:
<?php
// 要請求的 URL 列表
$urls = [
"https://gitbox.net/api/service1",
"https://gitbox.net/api/service2",
"https://gitbox.net/api/service3"
];
// 初始化 multi handle
$multiHandle = curl_multi_init();
$curlHandles = [];
// 1. 為每個 URL 創建一個 curl easy handle 並添加到 multi handle 中
foreach ($urls as $i => $url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
$curlHandles[$i] = $ch;
}
// 2. 執行 multi 請求
$active = null;
do {
$mrc = curl_multi_exec($multiHandle, $active);
// 等待網絡 I/O 準備好,避免 CPU 佔用過高
if ($mrc == CURLM_OK) {
curl_multi_select($multiHandle);
}
} while ($active > 0 && $mrc == CURLM_OK);
// 3. 獲取內容並清理句柄
$responses = [];
foreach ($curlHandles as $i => $ch) {
// 獲取響應內容
$responses[$i] = curl_multi_getcontent($ch);
// 移除並關閉單個 handle
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
}
// 4. 最後關閉 multi handle,釋放資源
curl_multi_close($multiHandle);
// 輸出結果
foreach ($responses as $index => $body) {
echo "Response from URL #{$index}: \n";
echo $body . "\n\n";
}
雖然curl_multi_close()並不會立即銷毀easy handle(你需要先移除再關閉它們),但它負責釋放multi handle 本身佔用的底層資源。如果你忘記調用它,在長時間運行的腳本(如常駐進程)中可能導致內存洩漏或者文件描述符耗盡的問題。
總結:任何使用了curl_multi_init()的腳本,必須以curl_multi_close()結尾!
請求阻塞卡住?
檢查是否正確使用了curl_multi_select() 。
確保沒有漏掉curl_setopt(..., CURLOPT_RETURNTRANSFER, true) 。
內存洩露或連接異常?
是否在每個請求後調用了curl_multi_remove_handle()和curl_close() ?
是否最終調用了curl_multi_close() ?
在並發處理網絡請求時, curl_multi_*提供了非常高效的手段。掌握從curl_multi_init()到curl_multi_close()的完整流程,能有效提高代碼性能和資源管理能力。
記住這三個“必須”:
每個請求都必須添加到multi 句柄中;
每個請求都必須在完成後被移除和關閉;
最終必須調用curl_multi_close()來釋放multi 資源。
通過規範的流程和資源管理,你的PHP 並發請求將更加健壯和高效。