2009-09-04 20 views
52

In realtà ho due domande.Intestazione solo recupero in php tramite arricciatura

(1) C'è qualche riduzione della potenza di elaborazione o larghezza di banda utilizzato su server remoto se recuperare solo le intestazioni in contrapposizione a tutta pagina il recupero utilizzando php e curl?

(2) Dal momento che penso, e potrei sbagliarmi, che la risposta alla prima domanda è SI, sto cercando di ottenere l'ultima data di modifica o If-Modified-Since intestazione del file remoto solo al fine di confrontare con la data-ora dei dati memorizzati localmente, quindi posso, nel caso sia stato modificato, memorizzarlo localmente. Tuttavia, il mio script non sembra in grado di recuperare quel pezzo di informazioni, ottengo NULL, quando corro questo:

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 
} 

} 

In caso $header = curl_exec($curl) viene vengono visualizzati i dati uncomented, intestazione, anche se non ne hanno fatto richiesta ed è come segue:

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 

In base a ciò, viene restituito 'Last-Modified'.

Quindi, cosa sto sbagliando?

risposta

47

Si sta passando $ intestazione a curl_getinfo(). Dovrebbe essere $curl (la maniglia di arricciatura). È possibile ottenere solo il filetime passando CURLINFO_FILETIME come secondo parametro a curl_getinfo(). (Spesso lo filetime non è disponibile, nel qual caso verrà segnalato come -1).

La tua classe sembra essere uno spreco, però, buttare via molte informazioni che potrebbero essere utili. Ecco un altro modo potrebbe essere fatto:

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ì, il carico sarà più leggero sul server, dal momento che è solo il ritorno solo l'header HTTP (rispondere, dopo tutto, ad una richiesta HEAD). Quanto più leggero sarà molto variabile.

+3

E 'da notare che il codice di cui sopra non restituirà alcun intestazioni , solo le informazioni vars. Per recuperare anche le intestazioni devi aggiungere 'curl_setopt ($ curl, CURLOPT_HEADER, true);'. Le intestazioni sono in forma di testo di lamentela e devono essere analizzate in seguito. – Lukas

15

(1) Sì. Una richiesta HEAD (come stai emettendo in questo caso) è molto più leggera sul server perché restituisce solo le intestazioni HTTP, a differenza delle intestazioni e dei contenuti come una richiesta GET standard.

(2) È necessario impostare l'opzione CURLOPT_RETURNTRANSFER per true prima di chiamare curl_exec() di avere il contenuto restituito, al contrario di stampa:

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

Questo dovrebbe anche fare il vostro lavoro di classe in modo corretto.

4

è necessario aggiungere

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

per tornare l'intestazione invece di stamparlo.

Se restituire solo le intestazioni è più leggero sul server dipende dallo script in esecuzione, ma in genere lo sarà.

Penso che tu voglia anche "filetime" invece di "datetime".

30

Perché utilizzare CURL per questo?C'è un PHP-funzione per questo:

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

restituisce il seguente:

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 
) 

dovrebbe essere facile per ottenere il tipo di contenuto dopo questo.

Si potrebbe anche aggiungere il formato = 1 a get_headers:

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

Questo restituirà il seguente:

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

Basta notare che in base ai documenti php questo farà una richiesta GET invece di una richiesta HEAD, che sembra inefficiente. http://www.php.net/manual/en/function.get-headers.php#example-4203 – Tim

+0

@Tim, infatti, non lo sapeva. Devo modificare questo post per riflettere il modo più efficace suggerito su PHP.NET? So che adatterò la mia programmazione a questo! – patrick

+3

CURL è necessario se qualcuno vuole ottenere un'intestazione mentre utilizza i cookie. – muaaz

3

È possibile impostare il contesto di flusso di default:

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

Quindi utilizzare:

$headers = get_headers($url,1); 

get_headers sembra essere più efficiente di cURL volta get_headers saltare i passaggi come routine di autenticazione grilletto, come log nei prompt o biscotti.

3

Ecco la mia implementazione utilizzando CURLOPT_HEADER, quindi parsing della stringa di uscita in una mappa: utilizzo

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

Esempio:

$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' 
) 
Problemi correlati