2011-09-27 7 views
6

Istnieje przekierowanie do serwera w celu uzyskania informacji, a gdy odpowiedź pochodzi z serwera, chcę sprawdzić kod HTTP, aby wygenerować wyjątek, jeśli istnieje kod zaczynający się od 4XX. W tym celu muszę wiedzieć, jak mogę uzyskać tylko kod HTTP z nagłówka? Także tutaj przekierowanie do serwera jest zaangażowane, więc obawiam się, że curl nie będzie dla mnie przydatny.Kod odpowiedzi HTTP po przekierowaniu

Do tej pory próbowałem this solution, ale jest bardzo powolny i tworzy limit czasu skryptu w moim przypadku. Nie chcę zwiększać limitu czasu skryptu i czekać dłużej, aby uzyskać kod HTTP.

Z góry dziękuję za wszelkie sugestie.

+2

cURL może obserwować przekierowania dobrze. Możesz przeczytać to w dokumentacji zamiast obawiać się swoich założeń: http://php.net/manual/en/function.curl-setopt.php, poszukaj 'CURLOPT_FOLLOWLOCATION' – Piskvor

+0

Próbowałem curl z opcją CURLOPT_FOLLOWLOCATION. Rzecz polega na pobraniu strony na mój lokalny serwer i kiedy wpisuję nazwę użytkownika/hasło na stronie, którą otrzymuję z serwera, serwer jest zdezorientowany w przekierowaniu. Jak rozwiązać ten problem? –

Odpowiedz

6

Coś jak:

$ch = curl_init(); 
    $httpcode = curl_getinfo ($ch, CURLINFO_HTTP_CODE); 

Należy starać klasę HttpEngine. Mam nadzieję, że to pomoże.

-

EDIT

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_USERAGENT, $your_agent_variable); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_REFERER, $your_referer); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 
curl_setopt($ch, CURLOPT_TIMEOUT, 5); 
$output = curl_exec($ch); 
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 
curl_close($ch); 

if ($httpcode ...) 
+0

Niestety nie jestem świadomy klasy HttpEngine. Czy możesz mi podać trochę informacji na ten temat? –

+0

Bez problemu. Cóż, nie pamiętam, skąd wziąłem tę klasę ... Więc przesłałem tę tutaj: http://pastebin.ca/2083612 powiedz mi, jeśli potrzebujesz pomocy! –

+0

Zajrzałem do pliku klasowego, ale nie wiem, w jaki sposób to pomoże. Używa zwijania i używania curl, gdy sprawię, że CURLOPT_FOLLOWLOCATION ma wartość true dla przekierowania, metoda GET pobiera całą stronę. –

0

Rozwiązanie znalazłeś wygląda dobrze. Jeśli serwer nie jest w stanie wysyłać nagłówków HTTP w porę, problem polega na tym, że drugi serwer jest zepsuty lub znajduje się pod bardzo dużym obciążeniem.

8

Twoja metoda z get_headers i zainteresowanie pierwszą linię odpowiedzi powróci kod statusu przekierowania (jeśli występują) i ważniejsze, będzie to zrobić żądania GET, który będzie przeniesienie całego pliku.

Potrzebne jest tylko żądanie HEAD, a następnie przeanalizowanie nagłówków i zwrócenie kodu stanu ostatniego. Poniżej znajduje się przykład kodu, który robi to, że używa $http_response_header zamiast get_headers, ale format tablicy jest taka sama:

$url = 'http://example.com/'; 

$options['http'] = array(
    'method' => "HEAD", 
    'ignore_errors' => 1, 
); 

$context = stream_context_create($options); 

$body = file_get_contents($url, NULL, $context); 

$responses = parse_http_response_header($http_response_header); 

$code = $responses[0]['status']['code']; // last status code 

echo "Status code (after all redirects): $code<br>\n"; 

$number = count($responses); 

$redirects = $number - 1; 

echo "Number of responses: $number ($redirects Redirect(s))<br>\n"; 

if ($redirects) 
{ 
    $from = $url; 

    foreach (array_reverse($responses) as $response) 
    { 
     if (!isset($response['fields']['LOCATION'])) 
      break; 
     $location = $response['fields']['LOCATION']; 
     $code = $response['status']['code']; 

     echo " * $from -- $code --> $location<br>\n"; 
     $from = $location; 
    } 
    echo "<br>\n"; 
} 

/** 
* parse_http_response_header 
* 
* @param array $headers as in $http_response_header 
* @return array status and headers grouped by response, last first 
*/ 
function parse_http_response_header(array $headers) 
{ 
    $responses = array(); 
    $buffer = NULL; 
    foreach ($headers as $header) 
    { 
     if ('HTTP/' === substr($header, 0, 5)) 
     { 
      // add buffer on top of all responses 
      if ($buffer) array_unshift($responses, $buffer); 
      $buffer = array(); 

      list($version, $code, $phrase) = explode(' ', $header, 3) + array('', FALSE, ''); 

      $buffer['status'] = array(
       'line' => $header, 
       'version' => $version, 
       'code' => (int) $code, 
       'phrase' => $phrase 
      ); 
      $fields = &$buffer['fields']; 
      $fields = array(); 
      continue; 
     } 
     list($name, $value) = explode(': ', $header, 2) + array('', ''); 
     // header-names are case insensitive 
     $name = strtoupper($name); 
     // values of multiple fields with the same name are normalized into 
     // a comma separated list (HTTP/1.0+1.1) 
     if (isset($fields[$name])) 
     { 
      $value = $fields[$name].','.$value; 
     } 
     $fields[$name] = $value; 
    } 
    unset($fields); // remove reference 
    array_unshift($responses, $buffer); 

    return $responses; 
} 

Aby uzyskać więcej informacji, patrz: HEAD first with PHP Streams na końcu zawiera przykładowy kod jak można wykonaj także żądanie HEAD z get_headers.

pokrewne: How can one check to see if a remote file exists using PHP?

+0

Powiązane: [PHP: get_headers ustaw tymczasowy strumień_kontekstu] (http://stackoverflow.com/questions/8429342/php-get-headers-set-temporary-stream-context) – hakre