爬蟲、API 串接時,常需分析完整 HTTP 交互:請求標頭、回應標頭、重導向鏈路、最終落地 URL。本文整理 cURL 關鍵選項與實用函式,助你精準掌握網路通訊細節。
$url = 'https://example.com/redirect.php'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); // 回應包含標頭 curl_setopt($ch, CURLOPT_NOBODY, 1); // 僅 HEAD 請求(不下載 body) curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 自動追蹤重導向 $content = curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch); echo $content; // 顯示回應標頭 print_r($info); // 顯示詳細傳輸資訊
curl_getinfo() 回傳陣列包含:url(最終有效 URL)、http_code、redirect_count、redirect_url 等關鍵欄位。
CURLOPT_FOLLOWLOCATION 會隱藏中間重導向 URL開啟自動追蹤後,curl_getinfo() 僅回傳最終 URL,無法取得中間 301/302 的 Location 標頭值。
function getRedirectLocation($url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 3);
// 關鍵:不可設 CURLOPT_NOBODY,否則 302 回應無 Location 標頭
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 關鍵:關閉自動追蹤,改由手動遞迴
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
$content = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
// 從標頭擷取 Location
if (preg_match('/Location:\s*(.+?)\s*/i', $content, $m)) {
$nextUrl = trim($m[1]);
// 處理相對路徑
if (strpos($nextUrl, 'http') !== 0) {
$parts = parse_url($url);
$nextUrl = $parts['scheme'].'://'.$parts['host'].($parts['port']?':'.$parts['port']:'').$nextUrl;
}
return getRedirectLocation($nextUrl); // 遞迴
}
return $info['url'] ?? $url; // 無重導向則回傳當前 URL
}
// 使用
$finalUrl = getRedirectLocation('https://example.com/start');
echo "最終 URL: $finalUrl";
| 選項 | 用途 | 注意 |
|---|---|---|
| CURLOPT_HEADER | 回應包含標頭 | 搭配 CURLOPT_RETURNTRANSFER 使用 |
| CURLOPT_NOBODY | 發送 HEAD 請求 | 開啟後無法獲取 302 Location,重導向分析時需關閉 |
| CURLOPT_FOLLOWLOCATION | 自動追蹤重導向 | open_basedir/safe_mode 限制下不可用,需手動實作 |
| CURLOPT_MAXREDIRS | 最大重導向次數 | 預設 20,防無限循環 |
| CURLOPT_SSL_VERIFYPEER | 驗證 SSL 憑證 | 測試環境可設 false,生產必須 true |
t.cn、bit.ly 等短連結真實目標。curl_getinfo() 的 total_time、namelookup_time、connect_time 分析瓶頸。掌握 cURL 細節,讓網路請求不再是黑盒子。