Como analisar headers de resposta em PHP?

Eu fiz um pedido assinado oauth para uma API REST e tenho os headers de resposta em uma matriz como assim:

[0] => HTTP/1.1 200 OK [1] => Cache-Control: private [2] => Transfer-Encoding: chunked [3] => Content-Type: text/html; charset=utf-8 [4] => Content-Location: https://*** [5] => Server: Microsoft-IIS/7.0 [6] => Set-Cookie: ASP.NET_SessionId=***; path=/; HttpOnly [7] => X-AspNetMvc-Version: 2.0 [8] => oauth_token: *** [9] => oauth_token_secret: *** [10] => X-AspNet-Version: 4.0.30319 [11] => X-Powered-By: ASP.NET [12] => Date: Sat, 15 Sep 2012 02:01:15 GMT 

Estou tentando descobrir como analisar os headers para facilitar a recuperação de itens como o código de status HTTP, Content-Location, oauth_token e oauth_token_secret?

   

Você precisará iterar a matriz e verificar stripos() para encontrar o header que você está procurando. Na maioria dos casos, você explode() em : (limitando para 2 partes resultantes), mas o código de resposta HTTP exigirá que você exploda nos espaços.

 // Get any header except the HTTP response... function getResponseHeader($header, $response) { foreach ($response as $key => $r) { // Match the header name up to ':', compare lower case if (stripos($r, $header . ':') === 0) { list($headername, $headervalue) = explode(":", $r, 2); return trim($headervalue); } } } // example: echo getResponseHeader("Content-Type"); // text/html; charset=utf-8 // Get the HTTP response code foreach ($response as $key => $r) { if (stripos($r, 'HTTP/1.1') === 0) { list(,$code, $status) = explode(' ', $r, 3); echo "Code: $code, Status: $status"; break; } } 

Parece que o único header sem uma : é a versão e o status do HTTP. Faça um array_shift para extrair isso, iterate através dos outros criando uma matriz como assim:

 $parsedHeaders = array(); foreach ($headers as $header) { if (! preg_match('^([^:]):(.*)$', $header, $output)) continue; $parsedArray[$output[1]] = $output[2]; } 

ps: não testado.

– editar –

apreciar 😉

 /** * Parse a set of HTTP headers * * @param array The php headers to be parsed * @param [string] The name of the header to be retrieved * @return A header value if a header is passed; * An array with all the headers otherwise */ function parseHeaders(array $headers, $header = null) { $output = array(); if ('HTTP' === substr($headers[0], 0, 4)) { list(, $output['status'], $output['status_text']) = explode(' ', $headers[0]); unset($headers[0]); } foreach ($headers as $v) { $h = preg_split('/:\s*/', $v); $output[strtolower($h[0])] = $h[1]; } if (null !== $header) { if (isset($output[strtolower($header)])) { return $output[strtolower($header)]; } return; } return $output; } 

Resposta curta se você tiver pecl_http: http://php.net/manual/it/function.explode.php

Resposta ligeiramente mais longa:

 $header = "..."; $parsed = array_map(function($x) { return array_map("trim", explode(":", $x, 2)); }, array_filter(array_map("trim", explode("\n", $header)))); 

Parece que você está usando a function get_headers , se assim for, use o segundo parâmetro desta function que substitui os valores numéricos das chaves da matriz de saída e as substitui por chaves de string, verifique o manual para a function get_headers.

um pequeno exemplo seria:

 < ?php $output = get_headers('http://google.com', 1); print_r($output); 

irá produzir algo como a seguinte matriz:

 Array ( [0] => HTTP/1.0 301 Moved Permanently [Location] => http://www.google.com/ [Content-Type] => Array ( [0] => text/html; charset=UTF-8 [1] => text/html; charset=ISO-8859-1 ) [Date] => Array ( [0] => Tue, 24 Sep 2013 11:57:10 GMT [1] => Tue, 24 Sep 2013 11:57:11 GMT ) [Expires] => Array ( [0] => Thu, 24 Oct 2013 11:57:10 GMT [1] => -1 ) [Cache-Control] => Array ( [0] => public, max-age=2592000 [1] => private, max-age=0 ) [Server] => Array ( [0] => gws [1] => gws ) [Content-Length] => 219 [X-XSS-Protection] => Array ( [0] => 1; mode=block [1] => 1; mode=block ) [X-Frame-Options] => Array ( [0] => SAMEORIGIN [1] => SAMEORIGIN ) [Alternate-Protocol] => Array ( [0] => 80:quic [1] => 80:quic ) [1] => HTTP/1.0 200 OK [Set-Cookie] => Array ( [0] => PREF=ID=58c8f706594fae17:FF=0:TM=1380023831:LM=1380023831:S=_ehOnNWODZqIarXn; expires=Thu, 24-Sep-2015 11:57:11 GMT; path=/; domain=.google.com [1] => NID=67=L85IlJW5yG4l9Suyf1LwKMUTcVHyGv4u9tuuMlBH4pfT1syOJvspcgRJ9uTde1xLTDhI2QcOG_fuJY3sfhw49mayT5WdMHnGeMyhh3SgFTRYVF0RAtBXXmjyDFzMqPKu; expires=Wed, 26-Mar-2014 11:57:11 GMT; path=/; domain=.google.com; HttpOnly ) [P3P] => CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info." ) 

melhor maneira sem http_parse_headers ();

 function strHeaders2Hash($r) { $o = array(); $r = substr($r, stripos($r, "\r\n")); $r = explode("\r\n", $r); foreach ($r as $h) { list($v, $val) = explode(": ", $h); if ($v == null) continue; $o[$v] = $val; } return $o; }