2009-09-04 16 views
52

En realidad, tengo dos preguntas.Recuperación de encabezado único en php a través de curl

(1) ¿Hay alguna reducción en la potencia de procesamiento o ancho de banda utilizado en el servidor remoto si puedo recuperar sólo los encabezados en contraposición a página completa recuperación utilizando php y el rizo?

(2) Dado que creo, y puedo estar equivocado, que la respuesta a la primera pregunta es , yo estoy tratando de conseguir la última fecha de modificación o If-Modified-Since encabezado del archivo remoto sólo con el fin de comparar con la fecha y hora de los datos almacenados localmente, por lo que puedo, en caso de que haya sido modificado, almacenarlo localmente. Sin embargo, mi guión parece incapaz de obtener esa pieza de información, consigo NULL, cuando corro esto:

se aparece
class last_change { 

public last_change; 

function set_last_change() { 
    $curl = curl_init(); 
    curl_setopt($curl, CURLOPT_URL, "http://url/file.xml"); 
    curl_setopt($curl, CURLOPT_HEADER, true); 
    curl_setopt($curl, CURLOPT_FILETIME, true); 
    curl_setopt($curl, CURLOPT_NOBODY, true); 
    // $header = curl_exec($curl); 
    $this -> last_change = curl_getinfo($header); 
    curl_close($curl); 
} 

function get_last_change() { 
    return $this -> last_change['datetime']; // I have tested with Last-Modified & If-Modified-Since to no avail 
} 

} 

En caso $header = curl_exec($curl) datos uncomented, cabecera, incluso si no lo han solicitado y es de la siguiente manera:

HTTP/1.1 200 OK 
Date: Fri, 04 Sep 2009 12:15:51 GMT 
Server: Apache/2.2.8 (Linux/SUSE) 
Last-Modified: Thu, 03 Sep 2009 12:46:54 GMT 
ETag: "198054-118c-472abc735ab80" 
Accept-Ranges: bytes 
Content-Length: 4492 
Content-Type: text/xml 

En función de eso, se devuelve 'Last-Modified'.

Entonces, ¿qué estoy haciendo mal?

Respuesta

47

Usted está pasando $ encabezado al curl_getinfo(). Debe ser $curl (el asa de curl). Puede obtener solo el filetime pasando CURLINFO_FILETIME como el segundo parámetro al curl_getinfo(). (A menudo, el filetime no está disponible, en cuyo caso se informará como -1).

Tu clase parece ser un desperdicio, tirando mucha información que podría ser útil. Aquí hay otra manera se podría hacer:

class URIInfo 
{ 
    public $info; 
    public $header; 
    private $url; 

    public function __construct($url) 
    { 
     $this->url = $url; 
     $this->setData(); 
    } 

    public function setData() 
    { 
     $curl = curl_init(); 
     curl_setopt($curl, CURLOPT_URL, $this->url); 
     curl_setopt($curl, CURLOPT_FILETIME, true); 
     curl_setopt($curl, CURLOPT_NOBODY, true); 
     curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
     curl_setopt($curl, CURLOPT_HEADER, true); 
     $this->header = curl_exec($curl); 
     $this->info = curl_getinfo($curl); 
     curl_close($curl); 
    } 

    public function getFiletime() 
    { 
     return $this->info['filetime']; 
    } 

    // Other functions can be added to retrieve other information. 
} 

$uri_info = new URIInfo('http://www.codinghorror.com/blog/'); 
$filetime = $uri_info->getFiletime(); 
if ($filetime != -1) { 
    echo date('Y-m-d H:i:s', $filetime); 
} else { 
    echo 'filetime not available'; 
} 

Sí, la carga será más ligero en el servidor, ya que sólo está devolviendo sólo la cabecera HTTP (responder, después de todo, a una petición HEAD). Cuánto más ligero variará mucho.

+3

Es de notar que el código anterior no devolverá los encabezados , solo la información vars. Para recuperar los encabezados también debe agregar 'curl_setopt ($ curl, CURLOPT_HEADER, true);'. Sin embargo, los encabezados vienen en formato de texto sin formato y necesitan ser analizados posteriormente. – Lukas

15

(1) Sí. Una solicitud HEAD (como lo está emitiendo en este caso) es mucho más ligera en el servidor porque solo devuelve los encabezados HTTP, a diferencia de los encabezados y el contenido, como una solicitud GET estándar.

(2) Es necesario configurar la opción CURLOPT_RETURNTRANSFER a true antes de llamar curl_exec() tener el contenido devuelto, en lugar de imprimir:

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

que también deben hacer su trabajo de la clase correctamente.

4

es necesario agregar

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

volver a la cabecera en lugar de imprimirlo.

Si volver solo los encabezados es más claro en el servidor depende de la secuencia de comandos que se está ejecutando, pero generalmente lo será.

Creo que también quiere "hora de archivo" en lugar de "fecha y hora".

30

¿Por qué usar CURL para esto?Hay un PHP-función para la que:

$headers=get_headers("http://www.amazingjokes.com/img/2014/530c9613d29bd_CountvonCount.jpg"); 
print_r($headers); 

devuelve lo siguiente:

Array 
(
    [0] => HTTP/1.1 200 OK 
    [1] => Date: Tue, 11 Mar 2014 22:44:38 GMT 
    [2] => Server: Apache 
    [3] => Last-Modified: Tue, 25 Feb 2014 14:08:40 GMT 
    [4] => ETag: "54e35e8-8873-4f33ba00673f4" 
    [5] => Accept-Ranges: bytes 
    [6] => Content-Length: 34931 
    [7] => Connection: close 
    [8] => Content-Type: image/jpeg 
) 

debe ser fácil de obtener el tipo de contenido después de esto.

También puede añadir el formato = 1 a get_headers:

$headers=get_headers("http://www.amazingjokes.com/img/2014/530c9613d29bd_CountvonCount.jpg",1); 
    print_r($headers); 

Esto devolverá lo siguiente:

Array 
(
    [0] => HTTP/1.1 200 OK 
    [Date] => Tue, 11 Mar 2014 22:44:38 GMT 
    [Server] => Apache 
    [Last-Modified] => Tue, 25 Feb 2014 14:08:40 GMT 
    [ETag] => "54e35e8-8873-4f33ba00673f4" 
    [Accept-Ranges] => bytes 
    [Content-Length] => 34931 
    [Connection] => close 
    [Content-Type] => image/jpeg 
) 

More reading here (PHP.NET)

+8

Solo tenga en cuenta que de acuerdo con los documentos php esto hará una solicitud GET en lugar de una solicitud HEAD, que parece ineficaz. http://www.php.net/manual/en/function.get-headers.php#example-4203 – Tim

+0

@Tim, de hecho, no lo sabía. ¿Debo editar esta publicación para reflejar la forma más eficiente sugerida en PHP.NET? ¡Sé que adaptaré mi programación a esto! – patrick

+3

CURL es necesario si alguien quiere obtener encabezado mientras usa cookies. – muaaz

3

Puede establecer el contexto de secuencia por defecto:

stream_context_set_default(
    array(
     'http' => array(
      'method' => 'HEAD' 
     ) 
    ) 
); 

A continuación, utilice:

$headers = get_headers($url,1); 

get_headers parece ser más eficiente que el enrollamiento vez get_headers se saltan pasos como rutinas de autenticación de disparo, como registro de indicaciones o galletas.

3

Aquí está mi aplicación utilizando CURLOPT_HEADER, a continuación, analizar la cadena de salida en un mapa: el uso

function http_headers($url){ 
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_URL, $url); 
    curl_setopt($ch, CURLOPT_NOBODY, true); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 
    curl_setopt($ch, CURLOPT_HEADER, true); 

    $headers = curl_exec($ch); 

    curl_close($ch); 

    $data = []; 
    $headers = explode(PHP_EOL, $headers); 
    foreach ($headers as $row) { 
     $parts = explode(':', $row); 
     if (count($parts) === 2) { 
      $data[trim($parts[0])] = trim($parts[1]); 
     } 
    } 

    return $data; 
}; 

muestra:

$headers = http_headers('https://i.ytimg.com/vi_webp/g-dKXOlsf98/hqdefault.webp'); 
print_r($headers); 

Array 
(
    ['Content-Type'] => 'image/webp' 
    ['ETag'] => '1453807629' 
    ['X-Content-Type-Options'] => 'nosniff' 
    ['Server'] => 'sffe' 
    ['Content-Length'] => 32958 
    ['X-XSS-Protection'] => '1; mode=block' 
    ['Age'] => 11 
    ['Cache-Control'] => 'public, max-age=7200' 
) 
Cuestiones relacionadas