Skip to content

Instantly share code, notes, and snippets.

@Robbert
Created October 12, 2013 12:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Robbert/6949488 to your computer and use it in GitHub Desktop.
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.
<?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