Created
October 12, 2013 12:25
-
-
Save Robbert/6949488 to your computer and use it in GitHub Desktop.
PHP function for testing for a media type in a Content-Type header, taking in account case insensitivity and the optional parameters like charset.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @author Robbert Broersma <http://robbertbroersma.nl/> | |
* @license Public Domain | |
*/ | |
/** | |
* @see http://tools.ietf.org/html/rfc2046#appendix-A | |
* @see http://www.w3.org/Protocols/rfc1341/4_Content-Type.html | |
*/ | |
function isMediaType($reference, $contentType) | |
{ | |
$a = parseContentType($reference); | |
$b = parseContentType($contentType); | |
return $a && $b && $a['type'] === $b['type'] && $a['subtype'] === $b['subtype']; | |
} | |
/** | |
* The type, subtype an charset of the Content-Type header are case insensitive, | |
* so for convenience they will be converted to lowercase. | |
* | |
* @param {String} str | |
* @return {Object} | |
*/ | |
function parseContentType($str) | |
{ | |
// Tokens can consist of any character except SPACE, CTLS and except the following: | |
// ()<>@,;:\"/[]?.= | |
// That results in the following regexp | |
// [^\x00-\x20()<>@,;:?.\="\[\]] | |
// CTLS are "<any US-ASCII control character (octets 0 - 31) and DEL (127)>" | |
// @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.2 | |
$media_type_regex = '/^(application|audio|image|message|multipart|text|video|x-[^\x00-\x20()<>@,;:?.\="\[\]]+)\/([^\x00-\x20()<>@,;:?.\="\[\]]+)(;.+)?$/i'; | |
$parameters_regex = '/(?:;\s*([^\x00-\x20()<>@,;:?.\="\[\]]+)=(([^\x00-\x20()<>@,;:?.\="\[\]]+|"([^"]*)")))/'; | |
if (preg_match($media_type_regex, $str, $matches)) | |
{ | |
$type = strtolower($matches[1]); | |
$subtype = strtolower($matches[2]); | |
$params = array(); | |
$charset = null; | |
if (isset($matches[3])) | |
{ | |
if (preg_match_all($parameters_regex, $matches[3], $matches, PREG_SET_ORDER)) | |
{ | |
foreach ($matches as $param) | |
{ | |
$name = strtolower($param[1]); | |
// There's one item for unquoted and another for quoted values. | |
if (isset($param[4])) | |
$value = $param[4]; | |
else if (isset($param[2])) | |
$value = $param[2]; | |
else | |
$value = ""; | |
$params[$name] = $value; | |
} | |
} | |
} | |
if (isset($params['charset'])) | |
{ | |
$charset = strtolower($params['charset']); | |
} | |
else | |
{ | |
if ($type === 'text' && $subtype === 'plain') | |
$charset = 'us-ascii'; | |
} | |
return array( | |
"type" => $type, | |
"subtype" => $subtype, | |
"charset" => $charset, | |
"params" => $params | |
); | |
} | |
return null; | |
} | |
var_dump(parseContentType('application/json')); | |
var_dump(parseContentType('application/json; charset=UTF-8')); | |
var_dump(parseContentType('text/html; id="abc"; charset="iso-8859-1"')); | |
var_dump(parseContentType('text/html; id="abc"; charset=iso-8859-1')); | |
var_dump(parseContentType('application/svg+xml')); | |
var_dump(parseContentType('text/plain')); | |
var_dump(isMediaType('application/json', 'application/JSON; charset="UTF-8"')); | |
var_dump(isMediaType('application/json', 'garbled"')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment