*/ class AcceptHeader extends \ArrayObject { /** * Constructor * * @param string $header Value of the Accept header * @return void */ public function __construct($header) { $acceptedTypes = $this->_parse($header); usort($acceptedTypes, [$this, '_compare']); parent::__construct($acceptedTypes); } /** * Parse the accept header and return an array containing * all the informations about the Accepted types * * @param string $data Value of the Accept header * @return array */ private function _parse($data) { $array = []; $items = explode(',', $data); foreach ($items as $item) { $elems = explode(';', $item); $mime = current($elems); $types = explode('/', $mime); if (!isset($types[1])) { continue; } $acceptElement = [ 'raw' => $mime, 'type' => trim($types[0]), 'subtype' => trim($types[1]), ]; $acceptElement['params'] = []; while (next($elems)) { list($name, $value) = explode('=', current($elems)); $acceptElement['params'][trim($name)] = trim($value); } $array[] = $acceptElement; } return $array; } /** * Compare two Accepted types with their parameters to know * if one media type should be used instead of an other * * @param array $a The first media type and its parameters * @param array $b The second media type and its parameters * @return int */ private function _compare($a, $b) { $a_q = isset($a['params']['q']) ? floatval($a['params']['q']) : 1.0; $b_q = isset($b['params']['q']) ? floatval($b['params']['q']) : 1.0; if ($a_q === $b_q) { $a_count = count($a['params']); $b_count = count($b['params']); if ($a_count === $b_count) { if ($r = $this->_compareSubType($a['subtype'], $b['subtype'])) { return $r; } else { return $this->_compareSubType($a['type'], $b['type']); } } else { return $a_count < $b_count; } } else { return $a_q < $b_q; } } /** * Compare two subtypes * * @param string $a First subtype to compare * @param string $b Second subtype to compare * @return int */ private function _compareSubType($a, $b) { if ($a === '*' && $b !== '*') { return 1; } elseif ($b === '*' && $a !== '*') { return -1; } else { return 0; } } }