2012-05-14 20 views
21

Próbuję uzyskać odpowiedź od nagłówków odpowiedzi z CURL przy użyciu PHP, specjalnie dla Content-Disposition: attachment; więc mogę zwrócić nazwę pliku przekazaną w nagłówku. To nie wydaje się być zwrócone w curl_getinfo.Zwracanie nagłówka jako tablicy przy użyciu Curl

Próbowałem używać funkcji HeaderFunction do wywoływania funkcji odczytu dodatkowych nagłówków, jednak nie mogę dodać zawartości do tablicy.

Czy ktoś ma jakieś pomysły, proszę?


Poniżej jest część mojego kodu, który jest Curl klasy otoki:

... 
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

Powinienem dodać, że funkcja readHeader jest częścią klasy zwijania. Używanie "$ this-> readHeader" nie działa. – StuffandBlah

+2

Zgodnie z dokumentami, twoja funkcja 'readHeader' musi zwracać liczbę zapisanych bajtów. Dodanie 'return strlen ($ header)' powinno spowodować, że to zadziała – marcfrodi

Odpowiedz

52

Tutaj powinien to zrobić:

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

To działa. Dziękuję Ci! – StuffandBlah

+4

nazwy nagłówków nie uwzględniają wielkości liter, więc lepiej jest użyć klawisza $. Również nagłówki mnożące mogą mieć taką samą nazwę/ – ruz

-3

można zrobić na 2 sposoby

  1. według zestawu curl_setopt ($ this -> _ ch, CURLOPT_HEADER, tru mi); pojawi się nagłówek z komunikatem odpowiedzi curl_exec(); należy wyszukać słowo kluczowe "Content-Disposition:" z komunikatu odpowiedzi.

  2. za pomocą tej funkcji get_headers ($ url) zaraz po wywołaniu curl_exec(). $ url to url zwany curl. return to tablica nagłówków. szukaj "Content-Disposition" w tablicy, aby uzyskać to, co chcesz.

+2

Używanie get_headers() może niepotrzebnie załadować serwer z drugim żądaniem HTTP i może bardzo dobrze dać zupełnie inny zestaw nagłówków. –

0

Używanie array() formularz dla metody wywołania zwrotne powinny oryginalnego przykładową pracę:

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

26

anwser z c.hill jest wielki, ale kod nie zajmie, jeśli pierwsza reakcja jest 301 lub 302 - w takim przypadku do tablicy zwróconej przez get_header_from_curl_response() zostanie dodany tylko pierwszy nagłówek.

Zaktualizowałem funkcję zwracania tablicy z każdym z nagłówków.

Najpierw używam tej linii, aby utworzyć zmienną tylko treść nagłówka

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

niż mijam $ nagłówek do nowego get_headers_from_curl_response() - funkcja:

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

Funkcja ta przyjmij nagłówek w ten sposób:

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 

I zwróć tablicę tak:

(
    [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

To zadziałało dla mnie. –

-1

Można użyć http_parse_headers funkcję.

Pochodzi od PECL, ale znajdziesz fallbacks in this SO thread.

+1

Być może trochę mylące jest stwierdzenie, że jest to "standard" - nie jest to standardowe rozszerzenie, np. nie jest dostarczany z PHP i nie ma oficjalnej wersji Windows. To także nadal '0.x', co oznacza, że ​​jest niestabilny. Nie będę na tym polegać, dopóki nie zostanie przynajmniej oznaczony jako stabilny, a najlepiej oficjalnie dołączony jako standardowe rozszerzenie PHP. –

+0

@ mindplay.dk masz rację: pochodząc z PECL nie jest standardem. W każdym razie pecl_http jest oznaczony jako stabilny od wersji 1.0.0 w 2006 roku, najnowszą stabilną wersją jest wersja 3.1.0. Przeformułowałem moją odpowiedź, aby było jaśniejsze. –

0

Kolejna moja realizacja:

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

używany w przypadku, który format żądania jest:

Host: *
Accept: *
Content-Length: *
i itp. ..

1

Proste i proste 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]; 
    } 
} 
Powiązane problemy