2009-09-04 14 views
52

Właściwie mam dwa pytania.Nagłówek tylko pobieranie w php poprzez curl

(1) Czy istnieje ograniczenie mocy obliczeniowej lub przepustowości używane na serwerze zdalnym, jeśli odzyskać tylko nagłówki w przeciwieństwie do pobierania pełnego widoku przy użyciu php i zwijać?

(2) Ponieważ myślę, a może się mylę, że odpowiedź na pierwsze pytanie jest TAK, próbuję uzyskać daty ostatniej modyfikacji lub If-Modified-Since nagłówku pliku zdalnego tylko w celu porównania to z datą lokalnie przechowywanych danych, więc mogę, na wypadek gdyby została zmieniona, przechowywać ją lokalnie. Jednakże mój skrypt wydaje stanie pobrać ten kawałek informacji, mam NULL, gdy uruchomię to:

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 
} 

} 

W przypadku $header = curl_exec($curl) jest wyświetlany dane uncomented, header, nawet jeśli nie mam o to i to w następujący sposób:

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 

Na tej podstawie zwracana jest "ostatnia modyfikacja".

Co więc robię źle?

Odpowiedz

47

Przekazujesz $ nagłówek do curl_getinfo(). Powinien to być $curl (rączka curl). Możesz uzyskać tylko filetime, przekazując CURLINFO_FILETIME jako drugi parametr do curl_getinfo(). (Często filetime jest niedostępny, w takim przypadku będzie raportowany jako -1).

Twoja klasa wydaje się być marnotrawstwem, ale wyrzuca wiele informacji, które mogą być przydatne. Oto kolejny sposób to można zrobić:

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

Tak, obciążenie będzie lżejszy na serwerze, ponieważ jest to tylko powrót tylko nagłówek HTTP (reaguje, mimo wszystko, na wniosek HEAD). O ile lżejsze będą się bardzo różnić.

+3

Należy zauważyć, że powyższy kod nie zwróci żadnych nagłówków , tylko informacje vars. Aby pobrać nagłówki, musisz dodać 'curl_setopt ($ curl, CURLOPT_HEADER, true);'. Nagłówki są jednak w formie tekstowej i należy je później przeanalizować. – Lukas

15

(1) Tak. Żądanie HEAD (tak jak to robisz w tym przypadku) jest znacznie jaśniejsze na serwerze, ponieważ zwraca tylko nagłówki HTTP, w przeciwieństwie do nagłówków i treści, takich jak standardowe żądanie GET.

(2) Należy ustawić opcję CURLOPT_RETURNTRANSFER do true przed wywołaniem curl_exec() mieć zawartość wrócił, w przeciwieństwie do drukowane:

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

To powinno również prawidłowo swoją pracę klasy.

4

Trzeba dodać

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

wrócić nagłówek zamiast drukować je.

To, czy zwracanie tylko nagłówków jest jaśniejsze na serwerze, zależy od działającego skryptu, ale zazwyczaj tak się stanie.

Myślę, że chcesz również "filetime" zamiast "datetime".

30

Dlaczego używać CURL do tego?Jest PHP-funkcyjny że:

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

zwraca następujący:

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 
) 

powinno być łatwe, aby uzyskać typ zawartości po tym.

Można też dodać format = 1 do get_headers:

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

ten powróci następujące:

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

Należy zauważyć, że zgodnie z dokumentami php będzie to zrobić żądanie GET zamiast żądania HEAD, co wydaje się nieefektywne. http://www.php.net/manual/en/function.get-headers.php#example-4203 – Tim

+0

@Tim, rzeczywiście, nie wiedziałem tego. Czy mam edytować ten post, aby odzwierciedlić bardziej efektywny sposób sugerowany w PHP.NET? Wiem, że dostosuję moje programowanie do tego! – patrick

+3

CURL jest niezbędny, jeśli ktoś chce uzyskać nagłówek podczas korzystania z plików cookie. – muaaz

3

Można ustawić domyślny kontekst strumieniowe:

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

Następnie użyj:

$headers = get_headers($url,1); 

get_headers wydaje się być bardziej skuteczne niż cURL raz get_headers pominąć kroki, takie jak wyzwalanie procedur uwierzytelniania, takich jak dziennik w podpowiedzi lub ciasteczka.

3

Tu jest moja realizacja za pomocą CURLOPT_HEADER, a następnie analizowania ciąg wyjściowy do mapy: Wykorzystanie

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

Próbka:

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