2012-05-14 21 views
21

Estoy tratando de obtener la respuesta & los encabezados de respuesta de CURL utilizando PHP, específicamente para Content-Disposition: archivo adjunto; para que pueda devolver el nombre de archivo pasado dentro del encabezado. Esto no parece ser devuelto dentro de curl_getinfo.Devolver encabezado como matriz usando Curl

He intentado usar HeaderFunction para llamar a una función para leer los encabezados adicionales, sin embargo, no puedo agregar el contenido a una matriz.

¿Alguien tiene alguna idea, por favor?


continuación es parte de mi código, que es una clase contenedora 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

Debo agregar que la función readHeader es parte de la clase de envoltura de curl. Usar '$ this-> readHeader' no funciona. – StuffandBlah

+2

De acuerdo con los documentos, su función 'readHeader' debe devolver el número de bytes escritos. Agregar 'return strlen ($ header)' debería hacer que esto funcione – marcfrodi

Respuesta

52

Aquí, esto debe hacerlo:

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

Eso hace el truco. ¡Gracias! Los nombres de encabezado – StuffandBlah

+4

son insensibles a las mayúsculas y minúsculas, por lo que es mejor bajar la $ key. Además, los encabezados de multiplicación pueden tener el mismo nombre/ – ruz

-3

se puede hacer de 2 maneras

  1. por conjunto curl_setopt ($ this -> _ ch, CURLOPT_HEADER, tru mi); El encabezado saldrá con un mensaje de respuesta de curl_exec(); debe buscar la palabra clave 'Content-Disposition:' del mensaje de respuesta.

  2. mediante el uso de esta función get_headers ($ url) justo después de llamar a curl_exec(). $ url se llama url en curl. el retorno es una matriz de encabezados. busque "Content-Disposition" en la matriz para obtener lo que desea.

+2

El uso de get_headers() cargará el servidor innecesariamente con una segunda solicitud HTTP, y muy bien podría dar un conjunto de encabezados completamente diferente. –

0

Utilizando el formulario para devoluciones de llamada array() método debe hacer el trabajo original ejemplo:

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

26

El anwser de c.hill es grande pero el código no manejará si la primera respuesta es una 301 o 302 - en ese caso, solo se agregará el primer encabezado a la matriz devuelta por get_header_from_curl_response().

He actualizado la función para devolver una matriz con cada uno de los encabezados.

Primero utilice estas líneas para crear una variable con sólo el contenido de la cabecera

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

De lo que pase de $ cabecera en la nueva get_headers_from_curl_response() - Función:

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

Esta función se tomar encabezado como este:

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 

Y devolver una matriz como esta:

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

Esto funcionó para mí. –

-1

Puede utilizar http_parse_headers función.

Viene de PECL pero encontrará fallbacks in this SO thread.

+1

Quizás un poco engañoso decir que esto es "estándar"; no es una extensión estándar, p. no se envía con PHP y no tiene una compilación oficial de Windows. También sigue siendo '0.x' lo que significa que es inestable. No dependería de esto hasta que al menos sea etiquetado como estable, y preferentemente empaquetado oficialmente como una extensión PHP estándar. –

+0

@ mindplay.dk tienes razón: venir de PECL no lo convierte en un estándar. De todos modos, pecl_http está etiquetado como estable desde la versión 1.0.0 en 2006, la última versión estable es la versión 3.1.0. Reformé mi respuesta para hacerlo más claro. –

0

Otro mi aplicación:

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

utiliza en el caso, el formato de solicitud es:

Host: *
Accept: *
Content-Length: *
y etc. ..

1

Simple y directo 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]; 
    } 
} 
Cuestiones relacionadas