當前位置: 首頁> 最新文章列表> 結合curl_exec 和curl_multi_close 使用的最佳實踐

結合curl_exec 和curl_multi_close 使用的最佳實踐

gitbox 2025-05-29

在開發中,我們經常需要向多個服務器或API發起HTTP請求。如果按照傳統的單線程方式,一個一個地請求,不僅慢,還浪費服務器資源。 PHP提供了cURL擴展,其中curl_multi_execcurl_multi_close函數可以讓我們實現多請求並發處理,大大提高效率。

本文將詳細介紹如何使用curl_exec結合curl_multi_close進行高效的並發處理,並給出具體的示例代碼。

基本概念

  • curl_exec() :執行單個cURL請求。

  • curl_multi_exec() :同時執行多個cURL句柄。

  • curl_multi_close() :關閉一個cURL批處理句柄,釋放資源。

如果需要並發處理大量請求,推薦使用curl_multi_exec ,而非為每個請求單獨調用curl_exec 。而curl_multi_close則是在全部請求處理完畢後,清理資源的重要步驟。

示例代碼

下面是一個簡單示例,演示如何並發請求多個接口,並處理響應:

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

// 初始化多個cURL句柄
$multiHandle = curl_multi_init();
$curlHandles = [];

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;
}

// 執行所有請求
$running = null;
do {
    $status = curl_multi_exec($multiHandle, $running);
    if ($status > 0) {
        // 有錯誤發生
        echo "cURL error: " . curl_multi_strerror($status);
        break;
    }
    // 等待活動連接
    curl_multi_select($multiHandle);
} while ($running > 0);

// 處理每個請求的響應
foreach ($curlHandles as $ch) {
    $response = curl_multi_getcontent($ch);
    $info = curl_getinfo($ch);
    if (curl_errno($ch)) {
        echo 'Request Error: ' . curl_error($ch) . PHP_EOL;
    } else {
        echo 'HTTP Code: ' . $info['http_code'] . PHP_EOL;
        echo 'Response: ' . $response . PHP_EOL;
    }
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}

// 關閉multi handle
curl_multi_close($multiHandle);
?>

說明

  • 首先通過curl_multi_init()創建一個多句柄。

  • 將每個cURL單獨設置後,通過curl_multi_add_handle()加入到multi handle中。

  • 使用curl_multi_exec()執行所有請求,通過輪詢的方式直到所有請求完成。

  • curl_multi_select()可以減少CPU空轉,提高效率。

  • 請求完成後,分別用curl_multi_getcontent()獲取響應內容。

  • 最後,記得使用curl_multi_remove_handle()移除句柄,並用curl_multi_close()關閉multi handle以釋放資源。

注意事項

  • 並發數量:如果一次性請求的URL太多,建議分批處理,比如每次只並發10個請求,避免佔用過多資源。

  • 超時處理:可以設置CURLOPT_TIMEOUTCURLOPT_CONNECTTIMEOUT來避免某些請求長時間掛起。

  • 錯誤處理:使用curl_errno()curl_error()檢查單個請求是否出錯。

  • 連接重用:開啟CURLOPT_FORBID_REUSE可以避免頻繁創建TCP連接,提高性能。

總結

通過結合使用curl_execcurl_multi_close ,我們可以在PHP中高效地處理大量HTTP並發請求。這種方式不僅可以縮短整體請求時間,還能充分利用服務器的並發能力,是構建高性能PHP應用的必備技能之一。

掌握這些基礎,你就能讓你的PHP應用跑得更快、更穩!