2012-05-14 29 views
21

Tôi đang cố gắng nhận phản hồi & tiêu đề phản hồi từ CURL bằng PHP, đặc biệt cho Nội dung Bố trí: tệp đính kèm; vì vậy tôi có thể trả về tên tệp được chuyển trong tiêu đề. Điều này dường như không được trả lại trong curl_getinfo.Trả lại tiêu đề dưới dạng mảng bằng cách sử dụng Curl

Tôi đã thử sử dụng HeaderFunction để gọi hàm để đọc tiêu đề bổ sung, tuy nhiên, tôi không thể thêm nội dung vào mảng.

Có ai có ý tưởng nào không?


Dưới đây là một phần của mã của tôi mà là một lớp wrapper Curl:

... 
curl_setopt($this->_ch, CURLOPT_URL, $this->_url); 
curl_setopt($this->_ch, CURLOPT_HEADER, false); 
curl_setopt($this->_ch, CURLOPT_POST, 1); 
curl_setopt($this->_ch, CURLOPT_POSTFIELDS, $this->_postData); 
curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($this->_ch, CURLOPT_USERAGENT, $this->_userAgent); 
curl_setopt($this->_ch, CURLOPT_HEADERFUNCTION, 'readHeader'); 

$this->_response = curl_exec($this->_ch); 
$info = curl_getinfo($this->_ch); 
... 


function readHeader($ch, $header) 
{ 
     array_push($this->_headers, $header); 
} 
+0

Tôi nên thêm hàm readHeader đó là một phần của lớp trình bao bọc curl. Sử dụng '$ this-> readHeader' không hoạt động. – StuffandBlah

+2

Theo tài liệu, hàm 'readHeader' của bạn phải trả về số byte được ghi. Thêm 'return strlen ($ header)' nên thực hiện công việc này – marcfrodi

Trả lời

52

Ở đây, điều này sẽ làm điều đó:

curl_setopt($this->_ch, CURLOPT_URL, $this->_url); 
curl_setopt($this->_ch, CURLOPT_HEADER, 1); 
curl_setopt($this->_ch, CURLOPT_RETURNTRANSFER, 1); 

$response = curl_exec($this->_ch); 
$info = curl_getinfo($this->_ch); 

$headers = get_headers_from_curl_response($response); 

function get_headers_from_curl_response($response) 
{ 
    $headers = array(); 

    $header_text = substr($response, 0, strpos($response, "\r\n\r\n")); 

    foreach (explode("\r\n", $header_text) as $i => $line) 
     if ($i === 0) 
      $headers['http_code'] = $line; 
     else 
     { 
      list ($key, $value) = explode(': ', $line); 

      $headers[$key] = $value; 
     } 

    return $headers; 
} 
+0

Điều đó thực hiện điều đó. Cảm ơn bạn! – StuffandBlah

+4

tên tiêu đề không phân biệt chữ hoa chữ thường, vì vậy có thể tốt hơn là viết hoa $. Ngoài ra, nhân tiêu đề có thể có cùng tên/ – ruz

-3

bạn có thể làm 2 cách

  1. bằng cách đặt curl_setopt ($ this -> _ ch, CURLOPT_HEADER, tru e); tiêu đề sẽ xuất hiện với thông báo phản hồi từ curl_exec(); bạn phải tìm kiếm từ khóa 'Nội dung-Bố trí:' từ thư trả lời.

  2. bằng cách sử dụng hàm get_headers này ($ url) ngay sau khi bạn gọi curl_exec(). $ url là url được gọi là curl. sự trở lại là mảng tiêu đề. tìm kiếm 'Nội dung-Bố trí' trong mảng để có được những gì bạn muốn.

+2

Sử dụng get_headers() sẽ tải máy chủ không cần thiết với yêu cầu HTTP thứ hai và có thể cung cấp một bộ tiêu đề hoàn toàn khác. –

0

Dùng mẫu array() cho callbacks phương pháp nên làm ví dụ tác phẩm gốc:

curl_setopt($this->_ch, CURLOPT_HEADERFUNCTION, array($this, 'readHeader'));

26

Các anwser từ c.hill là rất tốt nhưng mã sẽ không xử lý nếu phản ứng đầu tiên là một 301 hoặc 302 - trong trường hợp đó chỉ tiêu đề đầu tiên sẽ được thêm vào mảng được trả về bởi get_header_from_curl_response().

Tôi đã cập nhật hàm để trả về mảng với từng tiêu đề.

Trước tiên tôi sử dụng dòng này để tạo ra một biến chỉ với nội dung tiêu đề

$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 
$header = substr($a, 0, $header_size); 

Thần I vượt qua $ tiêu đề vào get_headers_from_curl_response mới() - Chức năng:

static function get_headers_from_curl_response($headerContent) 
{ 

    $headers = array(); 

    // Split the string on every "double" new line. 
    $arrRequests = explode("\r\n\r\n", $headerContent); 

    // Loop of response headers. The "count() -1" is to 
    //avoid an empty row for the extra line break before the body of the response. 
    for ($index = 0; $index < count($arrRequests) -1; $index++) { 

     foreach (explode("\r\n", $arrRequests[$index]) as $i => $line) 
     { 
      if ($i === 0) 
       $headers[$index]['http_code'] = $line; 
      else 
      { 
       list ($key, $value) = explode(': ', $line); 
       $headers[$index][$key] = $value; 
      } 
     } 
    } 

    return $headers; 
} 

Chức năng này sẽ lấy tiêu đề như sau:

HTTP/1.1 302 Found 
Cache-Control: no-cache 
Pragma: no-cache 
Content-Type: text/html; charset=utf-8 
Expires: -1 
Location: http://www.website.com/ 
Server: Microsoft-IIS/7.5 
X-AspNet-Version: 4.0.30319 
Date: Sun, 08 Sep 2013 10:51:39 GMT 
Connection: close 
Content-Length: 16313 

HTTP/1.1 200 OK 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Server: Microsoft-IIS/7.5 
X-AspNet-Version: 4.0.30319 
Date: Sun, 08 Sep 2013 10:51:39 GMT 
Connection: close 
Content-Length: 15519 

Và trả về mảng như sau:

(
    [0] => Array 
     (
      [http_code] => HTTP/1.1 302 Found 
      [Cache-Control] => no-cache 
      [Pragma] => no-cache 
      [Content-Type] => text/html; charset=utf-8 
      [Expires] => -1 
      [Location] => http://www.website.com/ 
      [Server] => Microsoft-IIS/7.5 
      [X-AspNet-Version] => 4.0.30319 
      [Date] => Sun, 08 Sep 2013 10:51:39 GMT 
      [Connection] => close 
      [Content-Length] => 16313 
     ) 

    [1] => Array 
     (
      [http_code] => HTTP/1.1 200 OK 
      [Cache-Control] => private 
      [Content-Type] => text/html; charset=utf-8 
      [Server] => Microsoft-IIS/7.5 
      [X-AspNet-Version] => 4.0.30319 
      [Date] => Sun, 08 Sep 2013 10:51:39 GMT 
      [Connection] => close 
      [Content-Length] => 15519 
     ) 

) 
+1

Điều này làm việc cho tôi. –

-1

Bạn có thể sử dụng chức năng http_parse_headers.

Nó đến từ PECL nhưng bạn sẽ tìm thấy fallbacks in this SO thread.

+1

Có thể có một chút sai lầm khi nói rằng đây là "chuẩn" - nó không phải là tiện ích mở rộng chuẩn, ví dụ: không gửi bằng PHP và không có bản dựng Windows chính thức. Nó cũng vẫn là '0.x' có nghĩa là nó không ổn định. Tôi sẽ không phụ thuộc vào điều này cho đến khi nó được gắn thẻ ít nhất là ổn định, và tốt hơn là chính thức đóng gói như là một phần mở rộng chuẩn PHP. –

+0

@ mindplay.dk bạn nói đúng: đến từ PECL không làm cho nó trở thành một tiêu chuẩn. Dù sao, pecl_http được gắn thẻ ổn định kể từ phiên bản 1.0.0 năm 2006, phiên bản ổn định mới nhất là phiên bản 3.1.0. Tôi viết lại câu trả lời của mình để làm cho nó rõ ràng hơn. –

0

Một thực hiện của tôi:

function getHeaders($response){ 

    if (!preg_match_all('/([A-Za-z\-]{1,})\:(.*)\\r/', $response, $matches) 
      || !isset($matches[1], $matches[2])){ 
     return false; 
    } 

    $headers = []; 

    foreach ($matches[1] as $index => $key){ 
     $headers[$key] = $matches[2][$index]; 
    } 

    return $headers; 
} 

Được sử dụng trong trường hợp, trong đó định dạng yêu cầu là:

Máy chủ: *
Chấp nhận: *
Content-Length: *
và vv. ..

1

Đơn giản và căng thẳng htforward

$headers = []; 
// Get the response body as string 
$response = curl_exec($curl); 
// Get the response headers as string 
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); 
// Get the substring of the headers and explode as an array by \r\n 
// Each element of the array will be a string `Header-Key: Header-Value` 
// Retrieve this two parts with a simple regex `/(.*?): (.*)/` 
foreach(explode("\r\n", trim(substr($response, 0, $headerSize))) as $row) { 
    if(preg_match('/(.*?): (.*)/', $row, $matches)) { 
     $headers[$matches[1]] = $matches[2]; 
    } 
} 
Các vấn đề liên quan