2011-02-23 23 views
6

curl_getinfo函數返回大量關於HTTP請求結果的元數據。但是,由於某些原因,它不包含我目前想要的信息位,如果請求返回HTTP重定向代碼,那麼這是目標URL。PHP cURL:獲取重定向目標,但不關注它

我沒有使用CURLOPT_FOLLOWLOCATION,因爲我想處理特定的重定向代碼作爲特殊情況。

如果cURL可以遵循重定向,爲什麼它不能告訴我他們在不跟隨它們時重定向到什麼?

當然,我可以設置CURLOPT_HEADER標誌並挑選位置標題。但是有沒有更高效的方法?

+0

CURLOPT_NOBODY? – HyderA 2011-02-23 12:59:11

+0

我的程序實際上使用了正文,在URL不是重定向的情況下。所以這根本不會改善事情。我的查詢基本上是關於是否有一種提取位置標題的方法,以節省在PHP代碼中執行它的開銷。 – Stewart 2011-02-23 16:40:06

+0

http://stackoverflow.com/questions/1439040/how-can-i-get-the-destination-url-using-curl – 2016-05-26 17:00:34

回答

0

沒有有沒有更有效的方法
你可以使用CURLOPT_WRITEHEADER + VariableStream
所以..你可以寫頭變量並解析它

+0

似乎爲我的目的矯枉過正......也許我現在只是使用一個簡單的回調我已經成功地理解了它們。 – Stewart 2011-02-26 12:21:09

2

curl似乎並不具備的功能或選項,以獲取

從響應

Apache可以響應重定向目標,則可以使用各種技術來提取在301重定向的情況下使用HTML頁面(似乎302不是這種情況)。

如果響應具有類似的格式:使用DOMXPath

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 
<html><head> 
<title>301 Moved Permanently</title> 
</head><body> 
<h1>Moved Permanently</h1> 
<p>The document has moved <a href="http://www.xxx.yyy/zzz">here</a>.</p> 
<hr> 
<address>Apache/2.2.16 (Debian) Server at www.xxx.yyy Port 80</address> 
</body></html> 

您可以提取重定向URL:

$i = 0; 
foreach($urls as $url) { 
    if(substr($url,0,4) == "http") { 
     $c = curl_init($url); 
     curl_setopt($c, CURLOPT_RETURNTRANSFER, true); 
     $result = @curl_exec($c); 
     $status = curl_getinfo($c,CURLINFO_HTTP_CODE); 
     curl_close($c); 
     $results[$i]['code'] = $status; 
     $results[$i]['url'] = $url; 

     if($status === 301) { 
      $xml = new DOMDocument(); 
      $xml->loadHTML($result); 
      $xpath = new DOMXPath($xml); 
      $href = $xpath->query("//*[@href]")->item(0); 
      $results[$i]['target'] = $href->attributes->getNamedItem('href')->nodeValue; 
     } 
     $i++; 
    } 
} 

使用CURLOPT_NOBODY

然而有一個更快的方法,如@gAMBOOKa指出;使用CURLOPT_NOBODY。這種方法僅發送HEAD請求而不是GET(不下載實際內容,所以它應該更快,更高效)並存儲響應頭。

使用一個正則表達式的目標URL可以從報頭中提取:

foreach($urls as $url) { 
    if(substr($url,0,4) == "http") { 
     $c = curl_init($url); 
     curl_setopt($c, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($c, CURLOPT_NOBODY,true); 
     curl_setopt($c, CURLOPT_HEADER, true); 
     $result = @curl_exec($c); 
     $status = curl_getinfo($c,CURLINFO_HTTP_CODE); 
     curl_close($c); 
     $results[$i]['code'] = $status; 
     $results[$i]['url'] = $url; 

     if($status === 301 || $status === 302) { 
      preg_match("@https?://([-\w\.]+)+(:\d+)?(/([\w/_\-\.]*(\?\S+)?)?)[email protected]",$result,$m); 
      $results[$i]['target'] = $m[0]; 
     } 
     $i++; 
    } 
} 
+0

CURLOPT_NOBODY獲勝!不可缺少的......謝謝! – Gor 2013-08-09 02:44:04

4

這可以在4個簡單的步驟來完成:

步驟1.初始化捲曲

curl_init($ch); //initialise the curl handle 
//COOKIESESSION is optional, use if you want to keep cookies in memory 
curl_setopt($this->ch, CURLOPT_COOKIESESSION, true); 

步驟2.獲取標題$url

curl_setopt($ch, CURLOPT_URL, $url); //specify your URL 
curl_setopt($ch, CURLOPT_HEADER, true); //include headers in http data 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); //don't follow redirects 
$http_data = curl_exec($ch); //hit the $url 
$curl_info = curl_getinfo($ch); 
$headers = substr($http_data, 0, $curl_info['header_size']); //split out header 

步驟3.檢查,如果你有正確的響應代碼

if (!($curl_info['http_code']>299 && $curl_info['http_code']<309)) { 
    //return, echo, die, whatever you like 
    return 'Error - http code'.curl_info['http_code'].' received.'; 
} 

第4步。解析頭以獲得新的URL

preg_match("!\r\n(?:Location|URI): *(.*?) *\r\n!", $headers, $matches); 
$url = $matches[1]; 

一旦你有了新的URL,那麼你可以經常爲你喜歡重複步驟2-4。

0

我有同樣的問題,並curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);有任何幫助。

所以,我決定不使用CURLfile_get_contents代替:

$data = file_get_contents($url); 
$data = str_replace("<meta http-equiv=\"Refresh\" content=\"0;","<meta",$data); 

最後一行幫我擋住重定向雖然該產品是不是一個乾淨的HTML代碼。

我解析了數據並可以檢索我想要獲得的重定向URL。

+0

它在我看來,好像您嘗試阻止重定向的頁面使用元刷新,而不是HTTP重定向。後者是我正在處理的。 – Stewart 2015-12-29 01:38:44

1

您可以簡單地使用它:(CURLINFO_REDIRECT_URL)

$info = curl_getinfo($ch, CURLINFO_REDIRECT_URL); 
echo $info; // the redirect URL without following it 

正如你所說,禁用CURLOPT_FOLLOWLOCATION選項(在執行前),並把我的代碼執行後。

CURLINFO_REDIRECT_URL - 隨着CURLOPT_FOLLOWLOCATION選項 禁用:重定向在過去的交易中發現的網址,應該 請手動旁邊。啓用CURLOPT_FOLLOWLOCATION選項 :這是空的。在這種情況下,重定向URL可在 CURLINFO_EFFECTIVE_URL

Refrence