2012-09-15 79 views
2

我做了一个OAuth签名的请求的REST API并具有响应头阵列中的像这样:如何解析PHP中的响应头?

[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 

我试图找出如何解析标头项目,如易于检索HTTP状态码,Content-Location,oauth_token和oauth_token_secret?

回答

6

您需要遍历数组并检查stripos()以查找要查找的标题。在大多数情况下,您在:explode()(限制为2个合成零件),但HTTP响应代码将要求您在空间上爆炸。

// 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; 
    } 
} 
+1

不,你不能这样做。这将盲目地返回不存在但包含字段名称的值。例如。 getResponseHeader(“会话”)将返回cookie。 – Phil

+0

响应代码假定为“HTTP/1.1”。还包含只有状态的第一个字被提取的错误。怎么样“HTTP/1.1 404找不到”。 – Phil

+0

@ Phil_1984_这是真的。一个左锚定的字符串匹配对于防止值匹配的问题是必要的,并且对状态代码进行稍微更智能的解析,并带有'explode()'限制。我稍后会在有空的时候修改它们(也是函数定义没有足够的参数)。您始终可以自由提出修改或发布新答案。 –

5

看起来,只有头部:是HTTP版本和状态。 做一个array_shift来提取,遍历别人创建一个数组,像这样:

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

PS:未经测试。

- 编辑 -

享受;)

/** 
* 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; 
} 
0

它看起来像你使用get_headers功能,如果是的话,可以使用此功能取代了数值为输出的第二个参数数组键并将其替换为字符串键,请查看manual以了解get_headers函数。

一个小例子是:

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

会产生类似下面的数组:

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." 
) 
0

简短的回答,如果您有pecl_http:http://php.net/manual/it/function.explode.php

稍长的答案:

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

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