1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
<?php function parse_accept_headers($default = 'html'){ $formats = array( 'text/html' => 'html', 'application/xhtml+xml' => 0, 'application/xml' => 0, '*/*' => 'html', ); $accept = array(); foreach (explode(',', $_SERVER['HTTP_ACCEPT']) as $header){ $parts = explode(';q=', $header); if (count($parts) === 1) $parts[1] = 1; $accept[$parts[0]] = $parts[1]; } arsort($accept); $accept[] = $default; foreach ($accept as $format => $q) if (array_key_exists($format, $formats) && $formats[$format]) break; return array($format, $formats[$format]); }
Refactorings
No refactoring yet !
fain182.myopenid.com
January 9, 2009, January 09, 2009 16:40, permalink
slightly improved..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
function parse_accept_headers($default = 'html'){
$formats = array(
'text/html' => 'html',
'application/xhtml+xml' => 0,
'application/xml' => 0,
'*/*' => 'html',
);
$accept = array();
foreach (explode(',', $_SERVER['HTTP_ACCEPT']) as $header){
list($mime, $q) = explode(';q=', $header);
$accept[$mime] = ($q === null)? 1 : $q;
}
arsort($accept);
$accept[] = $default;
foreach ($accept as $format => $q)
if ($formats[$format])
break;
return array($format, $formats[$format]);
}
Adam
January 9, 2009, January 09, 2009 22:27, permalink
To answer your question about valid characters, the spec is here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
<?php function parse_accept_headers($default = 'html') { return preferred_mime_type($_SERVER['HTTP_ACCEPT'], $default); } function preferred_mime_type($accept_header, $default = 'html') { $formats = array( 'text/html' => 'html', 'application/xhtml+xml' => 0, 'application/xml' => 0, '*/*' => 'html' ); foreach (parse_accept_header($accept_header) as list($mime_type, $q)) { if ($formats[$mime_type] == $default) { return array($mime_type, $default); } } return array(0, null); } function parse_accept_header($accept_header) { $accept_types = array_map(parse_accept_type, parse_accept_types($accept_header)); asort($accept_types); return $accept_types; } function parse_accept_types($accept_types) { return preg_split('/,\s*/', $accept_types); } function parse_accept_type($accept_type) { list($mime_type, $q) = preg_split('/;\s*q=/', $accept_type); return array($mime_type, $q ? $q : 1); } ?>
Todd
May 27, 2009, May 27, 2009 08:46, permalink
Just a tiny tweak to Adam's code, to remove the mime reference from parse_accept_type() so that parse_accept_header() and lower methods can also be used to parse HTTPAcceptLanguage headers, without the mime-specific reference found there. These could then also be called, for example, from a preferred_language() function similar to how preferred_mime_type() uses them now. It may be pedantic, but it does illustrate that this can be expanded beyond mime types. :)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
<?php function parse_accept_headers($default = 'html') { return preferred_mime_type($_SERVER['HTTP_ACCEPT'], $default); } function preferred_mime_type($accept_header, $default = 'html') { $formats = array( 'text/html' => 'html', 'application/xhtml+xml' => 0, 'application/xml' => 0, '*/*' => 'html' ); foreach (parse_accept_header($accept_header) as list($mime_type, $q)) { if ($formats[$mime_type] == $default) { return array($mime_type, $default); } } return array(0, null); } function parse_accept_header($accept_header) { $accept_types = array_map(parse_accept_type, parse_accept_types($accept_header)); asort($accept_types); return $accept_types; } function parse_accept_types($accept_types) { return preg_split('/,\s*/', $accept_types); } function parse_accept_type($accept_type) { list($type, $q) = preg_split('/;\s*q=/', $accept_type); return array($type, $q ? $q : 1); } ?>
Alex Trauzzi
July 18, 2009, July 18, 2009 15:52, permalink
For simplicity's sake, here's generating a key/value pair of mime types/values. Not much in the ways of validation, a worthwhile discussion awaits when it comes to whitespace...
Quick and dirty!
1 2 3 4 5 6 7
$AcceptViews = array();
// Build an array of the accept entries.
foreach(explode(",", $_SERVER['HTTP_ACCEPT']) as $value) {
$acceptLine = explode(";", $value);
$AcceptViews[$acceptLine[0]] = floatval(array_key_exists(1, $acceptLine) ? substr($acceptLine[1], 2) : 1);
}
arsort($AcceptViews);
a) define a list of MIME types and their corresponding local formats.
b) parse the HTTP Accept headers and pick the available format with the highest q value.
The explode parameter might not be enough - can there be spaces and other characters, not just ',' and ';q='?