當前位置: 首頁> 最新文章列表> 如何結合curl_multi_exec 和curl_multi_info_read 完成並行請求?

如何結合curl_multi_exec 和curl_multi_info_read 完成並行請求?

gitbox 2025-06-06

在PHP 中,如果你需要同時發起多個HTTP 請求,並希望這些請求能夠高效地並行執行, curl_multi_execcurl_multi_info_read是非常實用的函數。本文將詳細介紹如何利用這兩個函數實現高效並行請求,並給出具體代碼示例。


什麼是curl_multi_exec 和curl_multi_info_read?

  • curl_multi_exec :用於執行一組cURL句柄(curl handles),實現多路復用。它會並行地執行所有加入的請求。

  • curl_multi_info_read :用於獲取已經完成的請求的信息,可以檢測請求是否結束,從而處理相應的結果。


並行請求的基本思路

  1. 初始化多個單個的cURL請求(curl handles)。

  2. 創建一個多路復用句柄(multi handle)。

  3. 把所有單個請求加入到多路復用句柄中。

  4. 調用curl_multi_exec開始執行所有請求。

  5. 通過curl_multi_info_read不斷檢測是否有請求完成。

  6. 處理完成請求的結果。

  7. 清理資源。


詳細步驟及示例代碼

<?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 句柄時設置對應選項。