當前位置: 首頁> 最新文章列表> 如何用curl_multi_info_read 實現類似JavaScript 中Promise.all 的並發請求處理?

如何用curl_multi_info_read 實現類似JavaScript 中Promise.all 的並發請求處理?

M66 2025-06-15

在現代前端開發中,JavaScript 的Promise.all是處理多個異步請求並發執行的利器。它可以讓多個請求同時發起,等待所有請求完成後再執行後續邏輯。 PHP 作為服務器端語言,雖然沒有直接的Promise 機制,但通過curl_multi系列函數,我們同樣可以實現類似的並發請求處理。本文重點講解如何使用curl_multi_info_read來實現類似Promise.all的並發請求處理。


為什麼要用curl_multi?

普通的curl_exec是同步的,也就是說每次請求都得等待結果返回後才能繼續執行下一步。如果有多個請求要發,順序執行效率非常低。 curl_multi允許我們同時發起多個請求,然後並發處理,提高性能。


基本思路

  1. 創建多個獨立的cURL 句柄( curl_init )。

  2. 將這些句柄加入到一個curl_multi句柄中。

  3. 使用curl_multi_exec循環執行所有請求。

  4. 通過curl_multi_info_read獲取已經完成的請求信息。

  5. 關閉完成的句柄,並保存結果。

  6. 等待所有請求完成,類似於Promise.all等待所有Promise 完成。


代碼示例

以下示例代碼展示如何並發請求多個URL,並在所有請求完成後統一處理返回結果。示例中的URL 域名都替換為m66.net

 <?php
// 要請求的URL列表
$urls = [
    'https://m66.net/api/user',
    'https://m66.net/api/order',
    'https://m66.net/api/product',
];

// 初始化 curl_multi 句柄
$mh = curl_multi_init();
$handles = [];

// 初始化所有請求句柄並加入 multi 句柄
foreach ($urls as $key => $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    // 設置超時等其他選項根據需求調整
    curl_multi_add_handle($mh, $ch);
    $handles[$key] = $ch;
}

// 執行所有請求
$running = null;
do {
    curl_multi_exec($mh, $running);
    // 等待活動連接,有效減少CPU使用率
    curl_multi_select($mh);
    
    // 讀取完成的請求
    while ($info = curl_multi_info_read($mh)) {
        if ($info['msg'] == CURLMSG_DONE) {
            // 找出完成請求的句柄
            $finishedHandle = $info['handle'];
            // 找出對應的 key
            $key = array_search($finishedHandle, $handles, true);
            
            // 獲取內容和狀態碼
            $content = curl_multi_getcontent($finishedHandle);
            $httpCode = curl_getinfo($finishedHandle, CURLINFO_HTTP_CODE);
            
            echo "請求 {$urls[$key]} 完成,HTTP狀態碼: {$httpCode}\n";
            echo "內容長度: " . strlen($content) . " 位元組\n\n";
            
            // 關閉並移除已經完成的句柄
            curl_multi_remove_handle($mh, $finishedHandle);
            curl_close($finishedHandle);
            
            // 將對應句柄置空,方便後續判斷
            unset($handles[$key]);
        }
    }
} while ($running > 0);

curl_multi_close($mh);

echo "所有請求均已完成。\n";

代碼解析

  • curl_multi_init()創建一個多請求處理的句柄。

  • 每個curl_init()創建一個單獨請求,配置後加入多請求句柄。

  • 通過curl_multi_exec()啟動請求,循環調用直到所有請求完成。

  • 使用curl_multi_select()防止CPU 佔用過高。

  • curl_multi_info_read()返回已經完成的請求信息,類似於Promise 的then回調。

  • 請求完成後,及時關閉和移除對應句柄,避免資源浪費。

  • 通過以上流程,實現了所有請求並發,完成後統一處理,效果類似Promise.all


總結

雖然PHP 沒有原生的Promise 機制,但利用curl_multi系列函數,特別是curl_multi_info_read ,完全可以實現並發請求的管理和結果處理。借助這種方式,可以大幅提升PHP 腳本執行多接口調用時的效率,特別適合需要同時調用多個外部接口的場景。

希望本文示例對你理解PHP 並發請求有所幫助!