2010-12-14 19 views

Respuesta

24

Puede utilizar get_headers($url)

Ejemplo 2 a partir 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 
) 

El primer elemento de la matriz contendrá el código de estado de respuesta HTTP. Tienes que analizar eso.

Tenga en cuenta que la función get_headers en el ejemplo emitirá una solicitud HTTP HEAD, lo que significa que no recuperará el cuerpo de la URL. Esto es más eficiente que usar una solicitud GET que también devolverá el cuerpo.

También tenga en cuenta que estableciendo un por defecto contexto, cualquier llamada posterior utilizando un contexto de flujo http, ahora emitirá solicitudes HEAD. Así que asegúrese de restablecer el contexto predeterminado para usar GET nuevamente cuando haya terminado.

PHP también proporciona la variable $http_response_header

La matriz $http_response_header es similar a la función get_headers(). Al utilizar HTTP wrapper, $http_response_header se completará con los encabezados de respuesta HTTP. $http_response_header se creará en el ámbito local.

Si desea descargar el contenido de un recurso remoto, no desea hacer dos solicitudes (una para ver si el recurso existe y otra para recuperarlo), pero solo una. En ese caso, use algo como file_get_contents para buscar el contenido y luego inspeccione los encabezados de la variable.

+0

relacionadas: [? ¿Cómo se puede comprobar para ver si existe un archivo remoto usando PHP] (http://stackoverflow.com/questions/981954/how-can-one-check-to-see-if -a-remote-file-exists-using-php) (a través de: [HEAD primero con PHP Streams] (http://hakre.wordpress.com/2011/09/17/head-first-with-php-streams/)) – hakre

+0

Agregue un carácter @ al principio para suprimir la advertencia de php cuando la URL que se está probando no existe. De esa forma puedes lanzar tu propia excepción personalizada. –

+1

@FranciscoLuz Considero que usar la supresión de errores es un "no-go" y me conviene usar manejadores de errores apropiados. – Gordon

0

@Gordon - Aquí hay una rutina de biblioteca más completa basada en su respuesta. Incluye algunas verificaciones preliminares para la validez de URL, un poco más de manejo de errores y un análisis sintáctico de los encabezados devueltos. También sigue cualquier cadena de redirección para un número razonable de pasos.

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; 
    } 
} 

Con perdón de @FranciscoLuz - si usted está esperando errores en base a la entrada del usuario, el método "@ y error_get_last" parece perfectamente razonable para mí - No veo que haya nada más adecuada sobre el uso de set_error_handler .

Por cierto, no estoy seguro de si debería haber hecho esto como una edición de la respuesta de @Gordon en lugar de hacerlo como una respuesta separada. ¿Alguien puede aconsejar?

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; 
} 
Cuestiones relacionadas