Skip to content

Instantly share code, notes, and snippets.

@hugowetterberg
Created April 16, 2009 12:12
Show Gist options
  • Save hugowetterberg/96389 to your computer and use it in GitHub Desktop.
Save hugowetterberg/96389 to your computer and use it in GitHub Desktop.
Parsing headers, with focus on Content-* headers
<?php
/**
* Parsing headers with code adapted from the user contributed notes at
* http://php.net/manual/en/function.http-parse-headers.php
*
* @author Hugo Wetterberg, Good Old
*/
/*
// Sample usage
$headers = 'content-type: text/html; charset="UTF-8"; format=flowed'."\r\n".
'Content-disposition: attachment; filename="Hello \"World.txt"' . "\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";
$ph = parse_headers($headers);
print "Headers: \n";
print $headers;
print "\nBecomes: \n";
print_r($ph);
//*/
function 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]]) ) {
$retVal[$match[1]] = array($retVal[$match[1]], $match[2]);
} else {
$retVal[$match[1]] = trim($match[2]);
}
}
}
foreach ($retVal as $name => $value) {
switch ($name) {
case 'Content-Disposition':
case 'Content-Type':
$retVal[$name] = parse_content_header_value($value);
break;
}
}
return $retVal;
}
function parse_content_header_value($value) {
$retVal = array();
$value_pattern = '/^([^;]+)(;\s*(.+)\s*)?$/';
$param_pattern = '/([a-z]+)=(([^\"][^;]+)|(\"(\\\"|[^"])+\"))/';
$vm=array();
if (preg_match($value_pattern, $value, $vm)) {
$retVal['value'] = $vm[1];
if (count($vm)>2) {
$pm = array();
if (preg_match_all($param_pattern, $vm[3], $pm)) {
$pcount = count($pm[0]);
for ($i=0; $i<$pcount; $i++) {
$value = $pm[2][$i];
if (substr($value, 0, 1) == '"') {
$value = stripcslashes(substr($value, 1, mb_strlen($value)-2));
}
$retVal['params'][$pm[1][$i]] = $value;
}
}
}
}
return $retVal;
}
Headers:
content-type: text/html; charset="UTF-8"; format=flowed
Content-disposition: attachment; filename="Hello \"World.txt"
Server: Funky/1.0
Set-Cookie: foo=bar
Set-Cookie: baz=quux
Folded: works
too
Becomes:
Array
(
[Content-Type] => Array
(
[value] => text/html
[params] => Array
(
[charset] => UTF-8
[format] => flowed
)
)
[Content-Disposition] => Array
(
[value] => attachment
[params] => Array
(
[filename] => Hello "World.txt
)
)
[Server] => Funky/1.0
[Set-Cookie] => Array
(
[0] => foo=bar
[1] => baz=quux
)
[Folded] => works too
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment