En-tête HTTP Accept en PHP

L'en-tête HTTP « Accept » est une information envoyée par un logiciel effectuant une requête sur un serveur (typiquement : votre navigateur web qui demande d'afficher la page d'un site) et qui signifie à ce dernier le type de contenu qu'il accepte de recevoir. Et il est parfois nécessaire de décortiquer en détail cette information...

Voici par exemple ce que déclarent 3 navigateurs web dans l'en-tête HTTP Accept qu'ils envoient :

// Firefox 5
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

// Opera 11.50
text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1

// Chromium 14
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
En-tête HTTP « Accept » de différents navigateurs.

Le but du jeu est de récupérer une liste des types MIME acceptés, ordonnée selon la préférence du navigateur, afin de renvoyer une réponse au format le plus adéquat.

Il existe sur le web de nombreux scripts PHP effectuant ce traitement, certains de manière très poussée. je n'en indiquerai aucun vu que je n'ai eu le temps ni de les tester ni d'analyser leur code. A la place, voici une petite solution toute simple (voire trop) qui peut répondre à la plupart des besoins :

/**
 * Parser l'en-tête HTTP 'Accept' d'une requête
 * - On supprime les déclarations génériques ('*')
 * - A « poids » égal, on garde les types dans l'ordre 
 *   déclaré dans l'en-tête.
 *
 * @return {String[]} Liste ordonnée par ordre de 
 *      préférence des types MIME acceptés.
 */
function parseAcceptHeader () {
    $res = array();
    $accepts = explode(',', $_SERVER['HTTP_ACCEPT']);
    $n = count($accepts);
    foreach ($accepts as $key => $accept) {
        $params = explode(';', $accept);
        if (strpos($params[0], '*') === false)  {
            $mime = trim(array_shift($params));
            $v = $n - $key;
            foreach ($params as $param) {
                if (strpos($param, "q=") !== false) {
                    $w = explode('=', $param);
                    $v = (float) trim($w[1]);
                    break;
                }
            }
            $res[$mime] = $v;
        }            
    }
    arsort($res);
    return array_keys($res);
}
Fonction simple pour récupérer la liste des type MIME acceptés.

On obtient le résultat suivant :

// Firefox 5
Array
(
    [0] => text/html
    [1] => application/xhtml+xml
    [2] => application/xml
)
// Opera 11.50
Array
(
    [0] => text/html
    [1] => application/xhtml+xml
    [2] => image/png
    [3] => image/webp
    [4] => image/jpeg
    [5] => image/gif
    [6] => image/x-xbitmap
    [7] => application/xml
)
// Chromium 14
Array
(
    [0] => text/html
    [1] => application/xhtml+xml
    [2] => application/xml
)
Liste ordonée des types MIME acceptés.

On peut adopter le même algorithme pour lire l'en-tête « Accept-Language ».

FIELDING, Roy ; GETTYS, James ; MOGUL, Jeffrey, et al.. Hypertext Transfer Protocol - HTTP/1.1. W3C, . 14.1 Header Field Definitions : Accept

Content negotiation. Mozilla Developer Network, . The Accept: header