2009-09-04 35 views
52

Thực ra tôi có hai câu hỏi.Truy xuất chỉ tiêu đề trong php qua curl

(1) Có giảm sức mạnh xử lý hoặc băng thông sử dụng trên máy chủ từ xa nếu tôi lấy chỉ tiêu đề như trái ngược với hồi trang đầy đủ sử dụng php và cuộn tròn?

(2) Vì tôi nghĩ, và tôi có thể sai, câu trả lời cho câu hỏi đầu tiên là , tôi đang cố gắng để có được ngày sửa đổi cuối cùng hoặc tiêu đề If-Modified-Since của tệp từ xa chỉ để so sánh với dữ liệu được lưu trữ cục bộ theo thời gian, vì vậy tôi có thể, trong trường hợp dữ liệu đã được thay đổi, lưu trữ cục bộ. Tuy nhiên, kịch bản của tôi dường như không thể tìm nạp rằng mảnh thông tin, tôi nhận được NULL, khi tôi chạy này:

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 
} 

} 

Trong trường hợp $header = curl_exec($curl) được dữ liệu uncomented, tiêu đề được hiển thị, ngay cả khi tôi đã không yêu cầu nó và là như sau:

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 

Dựa vào đó, 'Sửa đổi lần cuối' được trả về.

Vì vậy, tôi đang làm gì sai?

Trả lời

47

Bạn đang chuyển $ header đến curl_getinfo(). Nó phải là $curl (tay cầm uốn cong). Bạn chỉ có thể nhận được số filetime bằng cách chuyển CURLINFO_FILETIME làm tham số thứ hai cho curl_getinfo(). (Thường thì filetime không khả dụng, trong trường hợp này nó sẽ được báo cáo là -1).

Lớp học của bạn dường như lãng phí, mặc dù, vứt bỏ rất nhiều thông tin có thể hữu ích. Dưới đây là một cách khác để nó có thể được thực hiện:

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

Vâng, tải sẽ nhẹ hơn trên máy chủ, vì nó chỉ trở về chỉ tiêu đề HTTP (trả lời, sau khi tất cả, một yêu cầu HEAD). Làm thế nào nhẹ hơn nhiều sẽ khác nhau rất nhiều.

+3

Đó là Cần lưu ý rằng các mã trên sẽ không trả lại bất kỳ tiêu đề , chỉ cần thông tin vars. Để lấy tiêu đề, bạn cần thêm 'curl_setopt ($ curl, CURLOPT_HEADER, true);'. Các tiêu đề có dạng văn bản thô sơ và cần được phân tích cú pháp sau đó. – Lukas

15

(1) Có. Một yêu cầu HEAD (như bạn đang phát hành trong trường hợp này) là nhẹ hơn trên máy chủ vì nó chỉ trả về các tiêu đề HTTP, trái với các tiêu đề và nội dung giống như một yêu cầu GET tiêu chuẩn.

(2) Bạn cần phải thiết lập các tùy chọn CURLOPT_RETURNTRANSFER để true trước khi bạn gọi curl_exec() có nội dung trở lại, như trái ngược với in:

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

Đó cũng nên làm cho công việc lớp học của bạn một cách chính xác.

4

Bạn cần phải thêm

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 

để trả lại tiêu đề thay vì in nó.

Việc chỉ trả về các tiêu đề nhẹ hơn trên máy chủ có phụ thuộc vào tập lệnh đang chạy hay không, nhưng thường thì nó sẽ là.

Tôi nghĩ bạn cũng muốn "filetime" thay vì "datetime".

30

Tại sao sử dụng CURL cho mục này?Có một PHP chức năng cho rằng:

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

trả về như sau:

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 
) 

nên được dễ dàng để có được những content-type sau này.

Bạn cũng có thể thêm các format = 1 tới get_headers:

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

này sẽ trở lại như sau:

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

Chỉ cần lưu ý rằng theo tài liệu php, điều này sẽ thực hiện yêu cầu GET thay vì yêu cầu HEAD, có vẻ như không hiệu quả. http://www.php.net/manual/en/function.get-headers.php#example-4203 – Tim

+0

@Tim, thực sự, không biết điều đó. Tôi có nên chỉnh sửa bài đăng này để phản ánh cách hiệu quả hơn được đề xuất trên PHP.NET không? Tôi biết tôi sẽ thích ứng với lập trình của mình với điều này! – patrick

+3

CURL là cần thiết nếu ai đó muốn nhận tiêu đề trong khi sử dụng cookie. – muaaz

3

Bạn có thể đặt bối cảnh luồng mặc định:

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

Sau đó sử dụng:

$headers = get_headers($url,1); 

get_headers có vẻ là hiệu quả hơn cURL lần get_headers bỏ qua bước như thói quen xác thực cò như log trong nhắc nhở hoặc cookie.

3

Đây được thực hiện tôi sử dụng CURLOPT_HEADER, sau đó phân tích các chuỗi đầu ra thành một bản đồ: sử dụng

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

mẫu:

$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' 
) 
Các vấn đề liên quan