2012-09-15 120 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; 
}