當前位置: 首頁> 最新文章列表> 如何在curl_multi_close 中實現請求的超時控制

如何在curl_multi_close 中實現請求的超時控制

gitbox 2025-05-12

在PHP 中, curl_multi_*系列函數可以讓你並發發送多個HTTP 請求,大大提高了程序的執行效率。不過,很多人在使用curl_multi_close結束多請求會話時,容易忽略一個重要問題:。

如果沒有合理控制超時時間,當某個請求長時間無響應時,整個應用可能被卡住,造成非常糟糕的用戶體驗。本文將通過示例,教你如何在使用curl_multi_close時,優雅地實現超時控制。

基本思路

其實, curl_multi_close只是用來關閉curl_multi句柄的,它本身不控制超時。真正的超時控制應該發生在執行請求(即curl_multi_execcurl_multi_select )的階段。

簡單說,超時控制靠的是:

  • 在單個curl 句柄上設置timeout

  • 在執行循環中自行記錄和判斷總耗時

示例代碼

下面是一個實際的示例。假設我們有兩個請求,分別請求https://gitbox.net/api/endpoint1https://gitbox.net/api/endpoint2 ,我們希望所有請求總耗時不能超過10 秒。

 <?php

// 創建兩個 cURL 句柄
$ch1 = curl_init('https://gitbox.net/api/endpoint1');
$ch2 = curl_init('https://gitbox.net/api/endpoint2');

// 給每個請求單獨設置超時(可選)
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_TIMEOUT, 8); // 單個請求最多8秒
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_TIMEOUT, 8);

// 創建一個 cURL 批處理句柄
$mh = curl_multi_init();

// 添加句柄到批處理句柄中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);

// 執行批處理
$startTime = microtime(true);
$timeout = 10; // 總超時時間(秒)

do {
    $status = curl_multi_exec($mh, $active);

    // 如果還有活動的連接
    if ($active) {
        // 阻塞等待
        $n = curl_multi_select($mh, 1.0);

        // 如果 select 返回 -1,避免忙等
        if ($n === -1) {
            usleep(100000); // 睡100毫秒
        }
    }

    // 檢查是否超時
    if ((microtime(true) - $startTime) > $timeout) {
        echo "請求總耗時超過{$timeout}秒,強制中斷。\n";
        break;
    }
} while ($active && $status == CURLM_OK);

// 讀取結果
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);

// 關閉句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
curl_close($ch1);
curl_close($ch2);

// 打印結果
echo "Response 1: " . substr($response1, 0, 100) . "...\n";
echo "Response 2: " . substr($response2, 0, 100) . "...\n";
?>

關鍵點總結

  1. CURLOPT_TIMEOUT控制單個請求的超時;

  2. 通過記錄microtime(true) ,手動控制總執行時間

  3. 使用curl_multi_select時要設定適當的超時值(比如1 秒),避免CPU 佔用過高;

  4. curl_multi_close只負責清理資源,不會控制任何超時邏輯

注意事項

  • 如果你設置了過短的select 超時時間(例如0.01秒),系統負載可能升高。

  • 如果curl_multi_select返回-1,意味著沒有文件描述符可以等待,需要適當睡眠( usleep ) 避免忙循環。

  • 當超時發生時,最好能主動取消未完成的請求,以避免資源洩漏。