在PHP 中,如果你需要同時發起多個HTTP 請求,並希望這些請求能夠高效地並行執行, curl_multi_exec和curl_multi_info_read是非常實用的函數。本文將詳細介紹如何利用這兩個函數實現高效並行請求,並給出具體代碼示例。
curl_multi_exec :用於執行一組cURL句柄(curl handles),實現多路復用。它會並行地執行所有加入的請求。
curl_multi_info_read :用於獲取已經完成的請求的信息,可以檢測請求是否結束,從而處理相應的結果。
初始化多個單個的cURL請求(curl handles)。
創建一個多路復用句柄(multi handle)。
把所有單個請求加入到多路復用句柄中。
調用curl_multi_exec開始執行所有請求。
通過curl_multi_info_read不斷檢測是否有請求完成。
處理完成請求的結果。
清理資源。
<?php
// 要請求的URL列表
$urls = [
'http://gitbox.net/api/endpoint1',
'http://gitbox.net/api/endpoint2',
'http://gitbox.net/api/endpoint3',
];
// 初始化 multi handle
$multiHandle = curl_multi_init();
$curlHandles = [];
// 1. 創建單個curl句柄,並加入multi句柄
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;
}
// 2. 執行所有請求
$running = null;
do {
// 執行請求
curl_multi_exec($multiHandle, $running);
// 可選:等待活動連接,防止CPU佔用過高
curl_multi_select($multiHandle);
// 3. 檢查是否有完成的請求
while ($info = curl_multi_info_read($multiHandle)) {
if ($info['msg'] === CURLMSG_DONE) {
$handle = $info['handle'];
// 獲取內容
$content = curl_multi_getcontent($handle);
// 處理返回內容,例如打印或解析
echo "請求完成,內容長度:" . strlen($content) . "\n";
// 移除完成的句柄,釋放資源
curl_multi_remove_handle($multiHandle, $handle);
curl_close($handle);
}
}
} while ($running > 0);
// 4. 關閉multi句柄
curl_multi_close($multiHandle);
?>
curl_multi_init() :初始化多路復用句柄。
curl_multi_add_handle() :把每個單獨請求的curl句柄添加到multi句柄。
curl_multi_exec() :執行所有請求。
curl_multi_select() :等待活動連接,避免cpu空轉。
curl_multi_info_read() :讀取完成請求的相關信息,判斷請求是否結束。
curl_multi_remove_handle()和curl_close() :清理資源,避免內存洩漏。
循環直到所有請求都完成( $running變為0)。
並行請求數量不要過大,避免服務器壓力過大或系統資源瓶頸。
使用curl_multi_select()進行等待,防止程序陷入高CPU佔用。
處理返回內容時要注意錯誤檢查,確保請求成功。
如果需要發起POST、帶header、認證等複雜請求,可以在初始化單個curl 句柄時設置對應選項。