PHP: cURL и отслеживать все перенаправления

Я просматриваю URL-адрес и отслеживаю каждый отдельный URL-адрес. По какой-то причине я не могу выполнить это, не выполняя рекурсивные вызовы cURL, которые не являются идеальными. Возможно, мне не хватает простого варианта. Мысли?

$url = "some url with redirects"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061024 BonEcho/2.0"); $html = curl_exec($ch); $info = array(); if(!curl_errno($ch)) { $info = curl_getinfo($ch); echo "<pre>"; print_r($info); echo "</pre>"; } 

и я получаю такой ответ

 Array ( [url] => THE LAST URL THAT WAS HIT [content_type] => text/html; charset=utf-8 [http_code] => 200 [header_size] => 1942 [request_size] => 1047 [filetime] => -1 [ssl_verify_result] => 0 [redirect_count] => 2 <---- I WANT THESE [total_time] => 0.799589 [namelookup_time] => 0.000741 [connect_time] => 0.104206 [pretransfer_time] => 0.104306 [size_upload] => 0 [size_download] => 49460 [speed_download] => 61856 [speed_upload] => 0 [download_content_length] => 49460 [upload_content_length] => 0 [starttransfer_time] => 0.280781 [redirect_time] => 0.400723 ) 

У тебя есть

 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 

Это означает, что cURL будет следовать переадресации и возвращать вам только последнюю страницу без заголовка местоположения.

Чтобы следить за местоположением вручную:

 function getWebPage($url, $redirectcallback = null){ $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_NOBODY, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061024 BonEcho/2.0"); $html = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($http_code == 301 || $http_code == 302) { list($httpheader) = explode("\r\n\r\n", $html, 2); $matches = array(); preg_match('/(Location:|URI:)(.*?)\n/', $httpheader, $matches); $nurl = trim(array_pop($matches)); $url_parsed = parse_url($nurl); if (isset($url_parsed)) { if($redirectcallback){ // callback $redirectcallback($nurl, $url); } $html = getWebPage($nurl, $redirectcallback); } } return $html; } function trackAllLocations($newUrl, $currentUrl){ echo $currentUrl.' ---> '.$newUrl."\r\n"; } getWebPage('some url with redirects', 'trackAllLocations'); 

Могу ли я сделать рекомендацию …

  preg_match('/(Location:|URI:)(.*?)\n/', $httpheader, $matches); 

измените регулярное выражение на /(Location:|URI:)(.*?)\n/i, поэтому он нечувствителен к регистру. Я заметил, что есть некоторые сайты / места, которые используют местоположение: где L – строчный.

Просто мысль помочь тем, кто задавался вопросом, почему иногда это не работает … смотрите на это.

С помощью libcurl вы можете использовать переменную getinfo CURLINFO_REDIRECT_URL, чтобы узнать URL, на который она была бы перенаправлена, если бы она была включена. Это позволяет программам легко пересекать редиректы.

Этот подход намного лучше и проще, чем синтаксический разбор Location: заголовки, предлагаемые здесь, так как тогда ваш код должен перестраивать относительные пути и т. Д. CURLINFO_REDIRECT_URL исправляет это для вас автоматически.

Связи PHP / CURL добавили поддержку этой функции в PHP 5.3.7:

 $url = curl_getinfo($ch, CURLINFO_REDIRECT_URL) 

Конец, который зафиксировал это: http://lxr.php.net/history/PHP-MASTER/ext/curl/interface.c#599d9134 (апрель 2011 г.)