當前位置: 首頁> 最新文章列表> curl_multi_close 的異步請求中,如何保持順序性

curl_multi_close 的異步請求中,如何保持順序性

gitbox 2025-05-12

在進行多個異步HTTP 請求時, cURL是PHP 中一種非常強大的工具。使用curl_multi_*函數,開發者可以同時發起多個請求,提高效率。 curl_multi_close函數用於關閉多重cURL 會話,但如何在進行異步請求時確保響應的順序性呢?因為curl_multi_exec可能會返回多個請求的響應,而這些響應的完成順序可能與請求的順序不同。

這篇文章將詳細解釋如何確保在使用curl_multi_close時,異步請求的結果能夠保持請求順序。

1. 什麼是curl_multi_* 函數?

curl_multi_*系列函數提供了一種通過並發請求來提升性能的方式。常用的幾個函數包括:

  • curl_multi_init() :初始化一個cURL 句柄,創建一個cURL 資源池。

  • curl_multi_add_handle() :將一個cURL 句柄添加到多重cURL 請求池中。

  • curl_multi_exec() :執行多個cURL 請求。

  • curl_multi_getcontent() :獲取每個請求的響應內容。

  • curl_multi_close() :關閉cURL 請求池,釋放資源。

這些函數常常一起使用來執行異步請求,從而提升性能。然而,由於響應的完成順序可能不同於請求的順序,如何確保響應結果的順序性成為一個重要問題。

2. 如何確保異步請求結果的順序性?

在進行異步請求時, curl_multi_exec會在後台同時發起多個請求,並等待所有請求完成。但是,這些請求的完成時間是不可預測的,因此它們的響應順序可能會打亂。

為了確保結果按順序處理,我們需要使用某種機制來記錄請求與響應之間的映射關係,常見的做法是使用關聯數組。具體來說,開發者可以為每個請求設置一個唯一標識符,並在接收到響應時根據這個標識符來正確排序結果。

下面是一個實現示例:

3. PHP 示例代碼

<?php

// 要請求的URL列表
$urls = [
    'https://gitbox.net/api/data1',
    'https://gitbox.net/api/data2',
    'https://gitbox.net/api/data3'
];

// 初始化 cURL multi 句柄
$mh = curl_multi_init();

// 請求句柄數組
$curl_handles = [];
$responses = [];
$index = 0;

// 為每個請求創建 cURL 句柄並添加到 multi 句柄中
foreach ($urls as $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    
    // 記錄每個請求的索引,以便響應按順序處理
    curl_multi_add_handle($mh, $ch);
    
    // 將句柄與索引關聯
    $curl_handles[(string)$ch] = $index++;
}

// 執行所有的 cURL 請求
$running = null;
do {
    curl_multi_exec($mh, $running);
    curl_multi_select($mh); // 讓程序等待直到有數據返回
} while ($running > 0);

// 读取每个請求的响应,并按請求的顺序保存结果
foreach ($curl_handles as $ch => $index) {
    $response = curl_multi_getcontent($ch);
    $responses[$index] = $response; // 按索引保存響應
    curl_multi_remove_handle($mh, $ch); // 移除句柄
    curl_close($ch); // 關閉每個句柄
}

// 最後關閉 multi 句柄
curl_multi_close($mh);

// 輸出響應結果,确保按照請求顺序输出
foreach ($responses as $response) {
    echo $response . PHP_EOL;
}
?>

4. 代碼解析

4.1 請求與響應的順序性

在上述代碼中,我們首先初始化了一個cURL multi 句柄,並為每個URL 創建了一個cURL 句柄。為了確保響應按順序返回,我們使用了一個關聯數組$curl_handles ,它將每個cURL 句柄與其在請求列表中的索引關聯起來。

當所有請求都完成後,我們遍歷這個關聯數組,並根據索引將每個響應存儲在$responses數組中,從而確保了響應的順序性。

4.2 異步執行與等待

使用curl_multi_exec執行所有請求時, running參數用於表示仍在執行的請求數量。 curl_multi_select會讓程序在沒有數據返回時阻塞,直到有請求完成,確保我們不會浪費CPU 資源。

4.3 釋放資源

最後,我們使用curl_multi_remove_handlecurl_close關閉所有的cURL 句柄,並使用curl_multi_close關閉多重cURL 句柄,釋放相關資源。

5. 總結

通過合理的使用關聯數組,我們可以確保在執行異步請求時,響應結果按請求順序返回。在PHP 中使用curl_multi_*系列函數來進行異步請求時,保持順序性是非常重要的,尤其是在處理多個接口的響應時。通過本示例,你可以更好地掌握如何在PHP 中進行異步請求並確保順序性,提升程序的性能和穩定性。