在現代前端開發中,JavaScript 的Promise.all是處理多個異步請求並發執行的利器。它可以讓多個請求同時發起,等待所有請求完成後再執行後續邏輯。 PHP 作為服務器端語言,雖然沒有直接的Promise 機制,但通過curl_multi系列函數,我們同樣可以實現類似的並發請求處理。本文重點講解如何使用curl_multi_info_read來實現類似Promise.all的並發請求處理。
普通的curl_exec是同步的,也就是說每次請求都得等待結果返回後才能繼續執行下一步。如果有多個請求要發,順序執行效率非常低。 curl_multi允許我們同時發起多個請求,然後並發處理,提高性能。
創建多個獨立的cURL 句柄( curl_init )。
將這些句柄加入到一個curl_multi句柄中。
使用curl_multi_exec循環執行所有請求。
通過curl_multi_info_read獲取已經完成的請求信息。
關閉完成的句柄,並保存結果。
等待所有請求完成,類似於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 並發請求有所幫助!