當前位置: 首頁> 最新文章列表> 如何使用curl_multi_close 清理多個並發請求的資源

如何使用curl_multi_close 清理多個並發請求的資源

gitbox 2025-05-12

在處理大量並發HTTP請求時, curl_multi系列函數是PHP中非常實用的工具。其中, curl_multi_close是收尾階段不可或缺的一步,用來正確釋放由curl_multi_init創建的資源。本文將講解curl_multi_close的正確用法,並提供一個實戰示例,幫助你避免常見的資源洩漏問題。

為什麼需要使用curl_multi_close

每當使用curl_multi_init創建一個多句柄(curl multi handle)時,PHP都會分配一塊內存用來管理這個多句柄及其包含的各個請求。即使單個子句柄( curl_init生成的)已經用curl_close關閉,整體的multi handle 依然會佔用系統資源。
如果忘記使用curl_multi_close ,在高並發場景下很容易引起內存洩露,甚至導致程序崩潰。

因此,在完成所有並發請求後,必須調用curl_multi_close來徹底釋放資源

基礎使用流程

一般使用curl_multi系列函數的流程如下:

  1. 創建multi handle( curl_multi_init

  2. 創建並配置多個單獨的curl handle( curl_init

  3. 將各個curl handle 加入multi handle( curl_multi_add_handle

  4. 執行並監控所有請求( curl_multi_execcurl_multi_select

  5. 移除單個handle( curl_multi_remove_handle )並關閉( curl_close

  6. 最後關閉multi handle( curl_multi_close

示例:並發請求多個接口並正確清理資源

下面是一個完整示例,展示瞭如何同時請求多個URL,並正確清理所有相關資源:

 <?php

// 要並發請求的URL列表
$urls = [
    "https://gitbox.net/api/endpoint1",
    "https://gitbox.net/api/endpoint2",
    "https://gitbox.net/api/endpoint3",
];

// 初始化 multi handle
$multiHandle = curl_multi_init();
$curlHandles = [];

// 初始化每個單獨的 curl handle 並加入 multi handle
foreach ($urls as $key => $url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_multi_add_handle($multiHandle, $ch);
    $curlHandles[$key] = $ch;
}

// 執行請求
$running = null;
do {
    $status = curl_multi_exec($multiHandle, $running);
    if ($status > CURLM_OK) {
        // 錯誤處理
        echo "cURL error: " . curl_multi_strerror($status);
        break;
    }

    // 等待活動連接
    curl_multi_select($multiHandle);
} while ($running > 0);

// 收集響應結果
$responses = [];
foreach ($curlHandles as $key => $ch) {
    $responses[$key] = curl_multi_getcontent($ch);
    // 移除並關閉每個子 handle
    curl_multi_remove_handle($multiHandle, $ch);
    curl_close($ch);
}

// 最後關閉 multi handle
curl_multi_close($multiHandle);

// 輸出響應
foreach ($responses as $index => $response) {
    echo "Response from URL {$urls[$index]}:" . PHP_EOL;
    echo $response . PHP_EOL . PHP_EOL;
}
?>

注意事項

  • 一定要先移除單個curl handle ,再關閉它們,最後關閉multi handle。

  • 不要直接關閉multi handle 後再操作子handle ,那樣會引發不可預期的錯誤。

  • 在高並發環境下建議加上超時控制CURLOPT_TIMEOUT ),防止長時間阻塞。

總結

curl_multi_close是保證資源合理釋放的最後一步,尤其在多並發場景下,養成良好的關閉習慣非常關鍵。正確地清理每個子句柄並最終關閉multi handle,能有效防止資源洩漏,提高PHP應用的穩定性和性能。