2010-12-14 16 views

Odpowiedz

24

można wykorzystywać get_headers($url)

przykładu 2 Manual:

<?php 
// By default get_headers uses a GET request to fetch the headers. If you 
// want to send a HEAD request instead, you can do so using a stream context: 
stream_context_set_default(
    array(
     'http' => array(
      'method' => 'HEAD' 
     ) 
    ) 
); 
print_r(get_headers('http://example.com')); 

// gives 
Array 
(
    [0] => HTTP/1.1 200 OK 
    [Date] => Sat, 29 May 2004 12:28:14 GMT 
    [Server] => Apache/1.3.27 (Unix) (Red-Hat/Linux) 
    [Last-Modified] => Wed, 08 Jan 2003 23:11:55 GMT 
    [ETag] => "3f80f-1b6-3e1cb03b" 
    [Accept-Ranges] => bytes 
    [Content-Length] => 438 
    [Connection] => close 
    [Content-Type] => text/html 
) 

Pierwszy element tablicy zawiera kod stanu odpowiedzi HTTP. Musisz to przeanalizować.

Należy pamiętać, że funkcja wyda żądanie HTTP HEAD, co oznacza, że ​​nie będzie pobierał treści adresu URL. Jest to bardziej wydajne niż użycie żądania GET, które również zwróci ciało.

Należy również pamiętać, że ustawienie domyślnego kontekstu powoduje, że wszelkie kolejne połączenia korzystające z kontekstu strumienia http będą teraz wywoływać żądania HEAD. Dlatego należy zresetować domyślny kontekst, aby ponownie użyć GET po zakończeniu.

PHP zapewnia również variable $http_response_header

Tablica $http_response_header jest podobna do funkcji get_headers(). Podczas korzystania z HTTP wrapper, $http_response_header zostaną wypełnione nagłówki odpowiedzi HTTP. $http_response_header zostanie utworzony w zasięgu lokalnym.

Jeśli chcesz pobrać zawartość zdalnego zasobu, nie chcesz wykonywać dwóch żądań (jedna sprawdza, czy zasób istnieje, a druga, aby go pobrać), ale tylko jedną. W takim przypadku użyj czegoś takiego, jak file_get_contents, aby pobrać zawartość, a następnie sprawdź nagłówki od zmiennej.

+0

pokrewne: [? Jak można sprawdzić, czy zdalny plik istnieje PHP] (http://stackoverflow.com/questions/981954/how-can-one-check-to-see-if -a-remote-file-exists-using-php) (przez: [HEAD pierwszy ze strumieniami PHP] (http://hakre.wordpress.com/2011/09/17/head-first-with-php-streams/)) – hakre

+0

Dodaj znak @ na początku, aby wyłączyć ostrzeżenie php, gdy testowany adres URL nie istnieje. W ten sposób możesz rzucić własny niestandardowy wyjątek. –

+1

@FranciscoLuz Uważam, że używanie tłumienia błędów nie jest zalecane i korzystam z właściwych procedur obsługi błędów. – Gordon

0

@Gordon - Oto bardziej kompletny program biblioteczny oparty na Twojej odpowiedzi. Zawiera wstępne sprawdzanie poprawności adresu URL, trochę więcej obsługi błędów i analizowanie zwróconych nagłówków. Podąża również za wszelkimi łańcuchami przekierowania w rozsądnej liczbie kroków.

class cLib { 
    static $lasterror = 'No error set yet'; 
    /** 
    * @brief See with a URL is valid - i.e. a page can be successfully retrieved from it without error 
    * @param string $url The URL to be checked 
    * @param int $nredirects The number of redirects check so far 
    * @return boolean True if OK, false if the URL cannot be fetched 
    */ 
    static function checkUrl($url, $nredirects = 0) { 
     // First, see if the URL is sensible 
     if (filter_var($url, FILTER_VALIDATE_URL) === false) { 
      self::$lasterror = sprintf('URL "%s" did not validate', $url); 
      return false; 
     } 
     // Now try to fetch it 
     $headers = @get_headers($url); 
     if ($headers == false) { 
      $error = error_get_last(); 
      self::$lasterror = sprintf('URL "%s" could not be read: %s', $url, $error['message']); 
      return false; 
     } 
     $status = $headers[0]; 
     $rbits = explode(' ', $status); 
     if (count($rbits) < 2) { 
      self::$lasterror = sprintf('Cannot parse status "%s" from URL "%s"', $status, $url); 
      return false; 
     } 
     if (in_array($rbits[1], array(301, 302, 304, 307, 308))) { 
      // This URL has been redirected. Follow the redirection chain 
      foreach ($headers as $header) { 
       if (cLib::startsWith($header, 'Location:')) { 
        if (++$nredirects > 10) { 
         self::$lasterror = sprintf('URL "%s" was redirected over 10 times: abandoned check', $url); 
         return false; 
        } 
        return self::checkUrl(trim(substr($header, strlen('Location:'))), $nredirects); 
       } 
      } 
      self::$lasterror = sprintf('URL "%s" was redirected but location could not be identified', $url); 
      return false; 
     } 
     if ($rbits[1] != 200) { 
      self::$lasterror = sprintf('URL "%s" returned status "%s"', $url, $status); 
      return false; 
     } 
     return true; 
    } 
} 

z przeprosinami do @FranciscoLuz - jeśli spodziewasz błędów na podstawie danych wprowadzonych przez użytkownika, metoda „@ i error_get_last” wydaje mi się zupełnie sensowne - nie widzę, że nie ma nic bardziej właściwy temat korzystania set_error_handler .

BTW, nie jestem pewien, czy powinienem był to zrobić jako odpowiedź na odpowiedź @ Gordona, a nie jako osobną odpowiedź. Czy ktoś może doradzić?

0
public function isLink($url) 
{ 
    $result = false; 
    if (!filter_var($url, FILTER_VALIDATE_URL) === false) { 
     $getHeaders = get_headers($url); 
     $result = strpos($getHeaders[0], '200') !== false; 
    } 
    return $result; 
} 
Powiązane problemy