http_parse_headers

(PECL pecl_http >= 0.10.0)

http_parse_headersHTTP ヘッダをパースする

説明

array http_parse_headers ( string $header )

HTTP ヘッダをパースし、連想配列に格納します。

パラメータ

header

HTTP ヘッダを含む文字列。

返り値

成功した場合に配列、 失敗した場合に FALSE を返します。

例1 http_parse_headers() の使用法

<?php
$headers 
"content-type: text/html; charset=UTF-8\r\n".
  
"Server: Funky/1.0\r\n".
  
"Set-Cookie: foo=bar\r\n".
  
"Set-Cookie: baz=quux\r\n".
  
"Folded: works\r\n\ttoo\r\n";
print_r(http_parse_headers($headers));
?>

上の例の出力は以下となります。

Array
(
  [Content-Type] => text/html; charset=UTF-8
  [Server] => Funky/1.0
  [Set-Cookie] => Array
  (
    [0] => foo=bar
    [1] => baz=quux
  )
  [Folded] => works
    too
)

参考

add a note add a note

User Contributed Notes 7 notes

up
4
ricardovermeltfoort at gmail dot com
11 years ago
I made a small mistake in http://www.php.net/manual/en/function.http-parse-headers.php#112986

The line
<?php
$headers
[0] = trim($h[0]);trim($h[0]);
?>
Should be changed to:
<?php
$headers
[0] = trim($h[0]);
?>
up
5
ricardovermeltfoort at gmail dot com
11 years ago
Taken from http://www.php.net/manual/en/function.http-parse-headers.php#112917 and modified to: make folded work too, return status in first key.

<?php
if (!function_exists('http_parse_headers'))
{
    function
http_parse_headers($raw_headers)
    {
       
$headers = array();
       
$key = ''; // [+]

       
foreach(explode("\n", $raw_headers) as $i => $h)
        {
           
$h = explode(':', $h, 2);

            if (isset(
$h[1]))
            {
                if (!isset(
$headers[$h[0]]))
                   
$headers[$h[0]] = trim($h[1]);
                elseif (
is_array($headers[$h[0]]))
                {
                   
// $tmp = array_merge($headers[$h[0]], array(trim($h[1]))); // [-]
                    // $headers[$h[0]] = $tmp; // [-]
                   
$headers[$h[0]] = array_merge($headers[$h[0]], array(trim($h[1]))); // [+]
               
}
                else
                {
                   
// $tmp = array_merge(array($headers[$h[0]]), array(trim($h[1]))); // [-]
                    // $headers[$h[0]] = $tmp; // [-]
                   
$headers[$h[0]] = array_merge(array($headers[$h[0]]), array(trim($h[1]))); // [+]
               
}

               
$key = $h[0]; // [+]
           
}
            else
// [+]
           
{ // [+]
               
if (substr($h[0], 0, 1) == "\t") // [+]
                   
$headers[$key] .= "\r\n\t".trim($h[0]); // [+]
               
elseif (!$key) // [+]
                   
$headers[0] = trim($h[0]);trim($h[0]); // [+]
           
} // [+]
       
}

        return
$headers;
    }
}
?>

Example:

<?php
$headers
= "HTTP/1.1 200 OK\r\n".
   
"content-type: text/html; charset=UTF-8\r\n".
   
"Server: Funky/1.0\r\n".
   
"Set-Cookie: foo=bar\r\n".
   
"Set-Cookie: baz=quux\r\n".
   
"Folded: works\r\n\ttoo\r\n";
print_r(http_parse_headers($headers));
?>

The above example will output:

Array
(
    [0] => HTTP/1.1 200 OK
    [content-type] => text/html; charset=UTF-8
    [Server] => Funky/1.0
    [Set-Cookie] => Array
        (
            [0] => foo=bar
            [1] => baz=quux
        )

    [Folded] => works
    too
)
up
5
Anonymous
11 years ago
if (!function_exists('http_parse_headers')) {
    function http_parse_headers ($raw_headers) {
        $headers = array(); // $headers = [];
  
        foreach (explode("\n", $raw_headers) as $i => $h) {
            $h = explode(':', $h, 2);
           
            if (isset($h[1])) {
                if(!isset($headers[$h[0]])) {
                    $headers[$h[0]] = trim($h[1]);
                } else if(is_array($headers[$h[0]])) {
                    $tmp = array_merge($headers[$h[0]],array(trim($h[1])));
                    $headers[$h[0]] = $tmp;
                } else {
                    $tmp = array_merge(array($headers[$h[0]]),array(trim($h[1])));
                    $headers[$h[0]] = $tmp;
                }
            }
        }
       
        return $headers;
    }
}
up
2
g dot kuizinas at anuary dot com
11 years ago
<?php

$headers
= "HTTP/1.1 302 Found
Server: nginx
Date: Sat, 27 Apr 2013 08:07:57 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 976
Connection: keep-alive
X-Frame-Options: sameorigin
X-Runtime: 443
Status: 302
Cache-Control: max-age=86400
Expires: Sun, 28 Apr 2013 08:07:56 GMT
Vary: Accept-Encoding,User-Agent
Strict-Transport-Security: max-age=3600 ; includeSubDomains"
;

if (!
function_exists('http_parse_headers')) {
    function
http_parse_headers ($raw_headers) {
       
$headers = [];
   
        foreach (
explode("\n", $raw_headers) as $i => $h) {
           
$h = explode(':', $h, 2);
           
            if (isset(
$h[1])) {
               
$headers[$h[0]] = trim($h[1]);
            }
        }
       
        return
$headers;
    }
}

var_dump(http_parse_headers($headers));
?>

array(12) {
  ["Server"]=>
  string(5) "nginx"
  ["Date"]=>
  string(29) "Sat, 27 Apr 2013 08:07:57 GMT"
  ["Content-Type"]=>
  string(24) "text/html; charset=utf-8"
  ["Content-Length"]=>
  string(3) "976"
  ["Connection"]=>
  string(10) "keep-alive"
  ["X-Frame-Options"]=>
  string(10) "sameorigin"
  ["X-Runtime"]=>
  string(3) "443"
  ["Status"]=>
  string(3) "302"
  ["Cache-Control"]=>
  string(13) "max-age=86400"
  ["Expires"]=>
  string(29) "Sun, 28 Apr 2013 08:07:56 GMT"
  ["Vary"]=>
  string(26) "Accept-Encoding,User-Agent"
  ["Strict-Transport-Security"]=>
  string(32) "max-age=3600 ; includeSubDomains"
}
up
0
cttr dot web at gmail dot com
8 years ago
Hi. Rewrote a function below comments
Github: https://github.com/mr-cttr/http_parse_headers

<?php
$headers
= "content-type: text/html; charset=UTF-8\r\n".
   
"Server: Nginx\r\n".
   
"set-cookie: user=\r\n\tunknown\r\n".
   
"set-cookie: pass=strong\r\n\tpassword\r\n".
   
"Set-Cookie: id=1\r\n".
   
"HOST:github.com";

http_parse_headers ($headers);

function
http_parse_headers ($raw)
    {
       
$k = '';
       
$out = [];

       
$exp = explode("\n", $raw);

        foreach (
$exp as $v) {
           
$exp = explode(':', $v, 2);

            if (isset(
$exp[1])) {
               
/** Сonvert to 'Word-Word' */
               
$k = strtolower($exp[0]);
               
$k = preg_replace_callback('/\b[a-z]/', function ($m) { return strtoupper($m[0]); }, $k);

               
$value = trim($exp[1]);

                if (!isset(
$out[$k])) $out[$k] = []; /** for in_array */
               
if (!in_array($value, $out[$k])) $out[$k][] = $value; /** New element in array */
           
} else {
               
$value = trim($exp[0]);

                if (!empty(
$exp[0][0]) && $exp[0][0] == "\t") {
                   
/** Index last element */
                   
end($out[$k]);
                   
$i = key($out[$k]);

                   
$out[$k][$i] .= "\r\n\t". $value;
                } elseif (!
$k)
                   
$out[0] = $value;
            }
        }

       
/** Array has only once element - convert in string */
       
$out = array_map(function ($v) { return count($v) < 2 ? $v[0] : $v; }, $out);

        return
$out;
    }
?>

Old function output with error

<?php
array (size=5)
 
'content-type' => string 'text/html; charset=UTF-8' (length=24)
 
'Server' => string 'Nginx' (length=5)
 
'set-cookie' => string 'Array // Notice: Array to string conversion

    password'
(length=16)
 
'Set-Cookie' => string 'id=1' (length=4)
 
'HOST' => string 'github.com' (length=10)
?>

My function output

<?php
array (size=4)
 
'Content-Type' => string 'text/html; charset=UTF-8' (length=24)
 
'Server' => string 'Nginx' (length=5)
 
'Set-Cookie' =>
    array (
size=3)
     
0 => string 'user=

    unknown'
(length=15)
     
1 => string 'pass=strong

    password'
(length=22)
     
2 => string 'id=1' (length=4)
 
'Host' => string 'github.com' (length=10)
?>
up
0
luigi dot sexpistols at gmail dot com
18 years ago
If you don't have access to the PECL library, you can use this code to parse headers contained in strings.

Note that it's probably not as robust as the PECL version, as it only parses if the headers are separated by newlines (\n). This isn't a problem in most cases, though, as the standard suggests to use \r\n as the delimiter for headers.

HTTP response code is put into 'status'.

Any suggestions welcome!

<?
function http_parse_headers($headers=false){
    if(
$headers === false){
        return
false;
        }
   
$headers = str_replace("\r","",$headers);
   
$headers = explode("\n",$headers);
    foreach(
$headers as $value){
       
$header = explode(": ",$value);
        if(
$header[0] && !$header[1]){
           
$headerdata['status'] = $header[0];
            }
        elseif(
$header[0] && $header[1]){
           
$headerdata[$header[0]] = $header[1];
            }
        }
    return
$headerdata;
    }

$headers = "HTTP/1.1 200 OK\r\n
Date: Tue, 08 Aug 2006 05:32:01 GMT\r\n
X-Powered-By: PHP/4.4.3-dev\r\n
Data 1: Value for Data 1\r\n
Data 2: Value for Data 2\r\n
Connection: close\r\n
Content-Type: text/html\r\n"
;

http_parse_headers($headers);

// OUTPUT:

array(7) {
  [
"status"]=>
 
string(15) "HTTP/1.1 200 OK"
 
["Date"]=>
 
string(29) "Tue, 08 Aug 2006 05:32:01 GMT"
 
["X-Powered-By"]=>
 
string(13) "PHP/4.4.3-dev"
 
["Data 1"]=>
 
string(16) "Value for Data 1"
 
["Data 2"]=>
 
string(16) "Value for Data 2"
 
["Connection"]=>
 
string(5) "close"
 
["Content-Type"]=>
 
string(9) "text/html"
}
?>
up
-1
Anonymous
11 years ago
This one works even better:

<?php

   
function http_parse_headers( $header )
    {
       
$retVal = array();
       
$fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header));
        foreach(
$fields as $field ) {
            if(
preg_match('/([^:]+): (.+)/m', $field, $match) ) {
               
$match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("\0")', strtolower(trim($match[1])));
                if( isset(
$retVal[$match[1]]) ) {
                    if (!
is_array($retVal[$match[1]])) {
                       
$retVal[$match[1]] = array($retVal[$match[1]]);
                    }
                   
$retVal[$match[1]][] = $match[2];
                } else {
                   
$retVal[$match[1]] = trim($match[2]);
                }
            }
        }
        return
$retVal;
    }

?>
To Top