在使用PHP 的cURL 擴展進行並發請求時, curl_multi_*系列函數非常常見。 curl_multi_close()是其中用來釋放資源、關閉cURL 句柄集合的函數。但不少開發者在處理包含重定向(如301、302)響應時,可能會疑惑: 以及,
本文將從原理和實踐角度,教你正確地使用curl_multi_close() ,避免在關閉請求時丟失重要的重定向響應。
首先要明白, curl_multi_close($multi_handle)的主要功能是:
關閉一個多句柄處理器(multi handle)
同時釋放關聯的所有資源
重要提示:
curl_multi_close()只負責資源清理,不會自動處理重定向。
重定向的處理必須在請求執行階段完成(比如在curl_multi_exec()前設置好選項)。
關閉後,你無法再取到任何請求響應數據,包括重定向信息。
因此,在調用curl_multi_close()之前,你必須確保所有請求已經完全執行完畢,並且已經讀取了需要的響應內容。
要讓cURL 正確跟隨重定向,並在關閉前拿到最終的響應,你應該這樣操作:
設置cURL 選項,允許自動跟隨重定向。
完全執行完請求,並且取回所有需要的數據。
最後調用curl_multi_close()釋放資源。
<?php
// 創建一個多句柄處理器
$multiHandle = curl_multi_init();
// 初始化單獨的 cURL 會話
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://gitbox.net/redirect-example');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 允許自動跟隨重定向
curl_setopt($ch, CURLOPT_MAXREDIRS, 5); // 最多跟隨5次重定向
// 将會話添加到多句柄处理器
curl_multi_add_handle($multiHandle, $ch);
// 執行請求
$running = null;
do {
$status = curl_multi_exec($multiHandle, $running);
if ($status > 0) {
echo "cURL Error: " . curl_multi_strerror($status);
}
// 等待活動連接
curl_multi_select($multiHandle);
} while ($running > 0);
// 在關閉之前獲取內容和信息
$response = curl_multi_getcontent($ch);
$info = curl_getinfo($ch);
// 打印響應內容
echo "Final URL: " . $info['url'] . PHP_EOL;
echo "HTTP Code: " . $info['http_code'] . PHP_EOL;
echo "Response Body: " . $response . PHP_EOL;
// 清理工作
curl_multi_remove_handle($multiHandle, $ch);
curl_close($ch);
curl_multi_close($multiHandle);
?>
CURLOPT_FOLLOWLOCATION設置為true ,自動處理重定向。
在curl_multi_exec完全執行完之後,使用curl_multi_getcontent()和curl_getinfo()獲取最終的響應信息。
只有在完全獲取數據後,才可以安全調用curl_multi_close() 。
如果你在curl_multi_close()之前沒有正確處理這些步驟,那麼你將無法得到重定向的最終響應數據。
下面是一個容易出錯的寫法:
<?php
$multiHandle = curl_multi_init();
$ch = curl_init('https://gitbox.net/redirect-example');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_multi_add_handle($multiHandle, $ch);
// 錯誤:執行未完成就直接關閉
curl_multi_close($multiHandle);
$response = curl_multi_getcontent($ch); // 此時獲取到的內容可能是空的或未定義
?>
問題分析:
請求尚未完成時就關閉了multi handle,導致後續無法正確獲取重定向響應和數據。
curl_multi_close()不會處理任何重定向,它只負責清理資源。
重定向必須通過設置CURLOPT_FOLLOWLOCATION ,並在關閉前完成請求處理。
在curl_multi_close()之前,務必提取所有需要的數據。
按正確順序(執行→ 獲取內容→ 移除handle → 關閉multi)才能確保請求完整、數據不丟失。
掌握這些細節,可以讓你在處理複雜的並發請求、特別是涉及重定向響應時,得心應手!