2011-12-08 11 views
6

Creo que get_headers de PHP no permite un contexto, por lo que tengo que cambiar el contexto de flujo predeterminado para obtener solo el encabezado de una solicitud. Esto causa algunos problemas con otras solicitudes en la página. Parece que no puedo averiguar cómo restablecer el contexto de flujo predeterminado. Estoy intentando algo como:PHP: get_headers establece temporal stream_context

$default = stream_context_get_default(); //Get default stream context so we can reset it 
stream_context_set_default(//Only fetch the HEAD 
     array(
    'http' => array(
     'method' => 'HEAD' 
    ) 
) 
); 
$headers = get_headers($url, 1); //Url can be whatever you want it to be 
//var_dump($headers); 
var_dump($default); 
stream_context_set_default($default); //This doesn't work as it expects an array and not a resource pointer 

¿Alguien sabe una solución para esto?

Sé que se ha sugerido usar Curl, pero preferiría no utilizarlo. ¡Gracias!

+0

get_headers inconsistencia: http://stackoverflow.com/questions/12781795/get-headers-inconsistency – Baba

Respuesta

8

Terminé usando la función stream_get_meta_data() para obtener los encabezados HTTP.

Ésta es la forma en que he implementado:

function get_headers_with_stream_context($url, $context, $assoc = 0) { 
    $fp = fopen($url, 'r', null, $context); 
    $metaData = stream_get_meta_data($fp); 
    fclose($fp); 

    $headerLines = $metaData['wrapper_data']; 

    if(!$assoc) return $headerLines; 

    $headers = array(); 
    foreach($headerLines as $line) { 
     if(strpos($line, 'HTTP') === 0) { 
      $headers[0] = $line; 
      continue; 
     } 

     list($key, $value) = explode(': ', $line); 
     $headers[$key] = $value; 
    } 

    return $headers; 
} 

llama así,

$context = stream_context_create(array('http' => array('method' => 'HEAD'))); 
$headers = get_headers_with_stream_context($url, $context, 1); 

le da lo que está después, dejando la stream_context estándar sin modificar.

Tenga en cuenta que esta función fallará si se le pasa algo que no sea una url http.

Parece haber un feature request para un argumento adicional para get_headers(), pero el rastreador de errores no está funcionando mientras escribo esto, por lo que no puedo buscar otras soluciones allí.

1

En lugar de la respuesta aceptada, hice lo siguiente, que trabajará en PHP 5.3 y superior, aunque no lo he probado totalmente. (También hay una stream_context_get_params($context) pero creo que esto es suficiente.)

$stream_context_defaults = stream_context_get_options(stream_context_get_default()); 
stream_context_set_default(
    array(
     'http' => array(
      'method' => 'HEAD' 
     ) 
    ) 
); 
for ($i = 1; $i <= 10; $i++) { 
    $headers = get_headers('http://www.example.org'); 
} 
stream_context_set_default($stream_context_defaults); // reset to defaults 
+1

Esto no siempre funciona, 'stream_context_set_default()' no puede ser "reset" con una gama $ vacío stream_context_defaults. – powtac

+1

¿Está documentado esto en alguna parte? Publiqué esto con el interés de intentar solucionar la falta de argumentos para get_headers. Me doy cuenta de que tal vez no sea el más inteligente establecer los valores predeterminados en lugar de crear un nuevo contexto, pero quería volver a utilizar el método get_headers. Sería bueno si get_headers tuviera la capacidad de pasar en un contexto personalizado, como file_get_contents. –

+0

No lo he visto claramente en los documentos. Lo descubrí probando. – powtac

4

tuve un problema similar, pero acabo de utilizar la función file_get_contents con el contexto de secuencia personalizada en lugar.

Así es como yo implementé:

$options = array(
       'http' => array(
        'method' => 'HEAD', 
        'follow_location' => 0 
       ) 
      ); 

$context = stream_context_create($options); 

@file_get_contents($url, NULL, $context); 

var_dump($http_response_header); 

Utilizando este contexto sólo los encabezados se fue a buscar por file_get_contents y poblarán la variable $http_response_header PHP.