How to parse response headers in PHP?

被刻印的时光 ゝ 提交于 2020-01-11 05:04:30

问题


I have made an oauth signed request to a REST API and have the response headers in an array like so:

[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

I am trying to figure out how to parse the headers for easy retrieval of items such as the HTTP status code, Content-Location, oauth_token, and oauth_token_secret?


回答1:


You'll need to iterate the array and check stripos() to find the header you're looking for. In most cases, you then explode() on : (limiting to 2 resultant parts), but the HTTP response code will require you to explode on the spaces.

// 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/') === 0) {
    list(,$code, $status) = explode(' ', $r, 3);
    echo "Code: $code, Status: $status";
    break;
  }
}



回答2:


It seems that the only header withou a : is the HTTP version and status. Do an array_shift to extract that, iterate through the others creating an array like so:

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

ps: untested.

— edit —

enjoy ;)

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



回答3:


Short answer if you have pecl_http: http://php.net/manual/it/function.explode.php

Slightly longer answer:

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



回答4:


best way without 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;
}



回答5:


I ended up with this solution which uses regex to find all the keys and values in the header combined with some array mutation from https://stackoverflow.com/a/43004994/271351 to get the regex matches into an associative array. This isn't 100% appropriate for the problem asked here since it takes in a string, but joining an array of strings to get a single string would work as a precursor to this. My case had to deal with raw headers, thus this solution.

preg_match_all('/^([^:\n]*): ?(.*)$/m', $header, $headers, PREG_SET_ORDER);
$headers = array_merge(...array_map(function ($set) {
    return array($set[1] => trim($set[2]));
}, $headers));

This yields an associative array of the headers. If the first line of the headers is included as input (e.g. GET / HTTP/1.1), this will ignore it for the output.




回答6:


It looks like you're using get_headers function, if so, use the second parameter of the this function which replaces the numerical values for the output array keys and replaces them with string keys, check out the manual for get_headers function.

a small example would be:

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

will produce something like the following array:

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


来源:https://stackoverflow.com/questions/12433958/how-to-parse-response-headers-in-php

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!