326 votes

Comment lire l'en-tête d'une requête en PHP ?

Comment lire un en-tête en PHP ?

Par exemple, l'en-tête personnalisé : X-Requested-With .

0 votes

"N'importe quel en-tête" est ambigu. Vous ne pouvez pas lire "n'importe quel en-tête" en une seule opération, mais vous pouvez lire séparément la liste entrante des en-têtes de demande et la liste sortante courante des en-têtes de réponse.

431voto

Jacco Points 12528

SI : vous n'avez besoin que d'un seul en-tête, au lieu de tous la méthode la plus rapide est :

<?php
// Replace XXXXXX_XXXX with the name of the header you need in UPPERCASE (and with '-' replaced by '_')
$headerStringValue = $_SERVER['HTTP_XXXXXX_XXXX'];

ELSE SI : vous exécutez PHP en tant que module Apache ou, à partir de PHP 5.4, en utilisant FastCGI (méthode simple) :

apache_request_headers()

<?php
$headers = apache_request_headers();

foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
}

ELSE : Dans tous les autres cas, vous pouvez utiliser (implémentation userland) :

<?php
function getRequestHeaders() {
    $headers = array();
    foreach($_SERVER as $key => $value) {
        if (substr($key, 0, 5) <> 'HTTP_') {
            continue;
        }
        $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
        $headers[$header] = $value;
    }
    return $headers;
}

$headers = getRequestHeaders();

foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
}

Voir aussi :
getallheaders() - (PHP >= 5.4) édition multiplateforme Alias de apache_request_headers() apache_response_headers() - Récupérer tous les en-têtes de réponse HTTP.
headers_list() - Récupère une liste d'en-têtes à envoyer.

3 votes

Je suppose que cela n'est possible que si l'on utilise le serveur Apache... il faudrait peut-être le faire savoir à l'OP :)

16 votes

Je ne me soucie pas de 82% des amateurs. Je m'intéresse aux installations professionnelles. Personne dans un bon état d'esprit n'essaierait de faire fonctionner un site à fort trafic avec mod_php.

13 votes

@Jacco Oui, et je pense que c'est une raison parfaite pour le downvoting. À tout moment, la meilleure réponse devrait être votée et les mauvaises réponses rétrogradées. Ce n'est pas un site de solutions historiques :-)

382voto

Quassnoi Points 191041
$_SERVER['HTTP_X_REQUESTED_WITH']

RFC3875 , 4.1.18 :

Méta-variables dont le nom commence par HTTP_ contiennent des valeurs lues à partir des champs d'en-tête de la demande du client, si le protocole utilisé est HTTP. Le nom du champ d'en-tête HTTP est converti en majuscules, toutes les occurrences de - remplacé par _ et a HTTP_ ajouté en préambule pour donner le nom de la méta-variable.

7 votes

Puis-je m'attendre à ce qu'un serveur mette tous les en-têtes dans le fichier $_SERVER ? La documentation PHP à l'adresse php.net/manual/fr/reserved.variables.server.php est évasif sur ce que nous pouvons être sûrs qu'il y aura dedans.

4 votes

Cela ne fonctionnera pas (toujours), en particulier avec PHP-fpm (ou cgi). Cet en-tête n'est pas toujours disponible dans PHP.

0 votes

En utilisant cette solution, je ne vois que certains des en-têtes de la requête, et dans ce cas, je ne vois pas celui que je veux. Chrome envoie un cache-control mais je ne le vois nulle part dans l'en-tête de l'UE. $_SERVER . Je vois plusieurs en-têtes préfixés par HTTP_ dont "HTTP_ACCEPT", et "HTTP_UPGRADE_INSECURE_REQUESTS" et "HTTP_USER_AGENT" (parmi plusieurs autres). Mais rien pour "cache-control" et rien non plus pour "pragma". Ceci indépendamment de la casse ou HTTP_ préfixe. Est-ce que quelque chose m'échappe ?

59voto

Thomas Jensen Points 794

Vous devriez trouver tous les en-têtes HTTP dans le fichier $_SERVER variable globale préfixée par HTTP_ en majuscules et avec des tirets (-) remplacés par des traits de soulignement (_).

Par exemple, votre X-Requested-With peuvent être trouvés dans :

$_SERVER['HTTP_X_REQUESTED_WITH']

Il peut s'avérer pratique de créer un tableau associatif à partir de l'information suivante $_SERVER variable. Cela peut être fait de plusieurs manières, mais voici une fonction qui produit des touches en majuscules :

$headers = array();
foreach ($_SERVER as $key => $value) {
    if (strpos($key, 'HTTP_') === 0) {
        $headers[str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;
    }
}

Maintenant, il suffit d'utiliser $headers['XRequestedWith'] pour récupérer l'en-tête souhaité.

Manuel PHP sur $_SERVER : http://php.net/manual/en/reserved.variables.server.php

3 votes

La meilleure réponse, à mon avis, est l'explication de Thomas avec le résultat final de Quassnoi. Un tableau associatif n'est généralement pas ce dont on a besoin, et il n'est pas très facile de trouver la solution simple en lisant l'explication de Thomas. parseRequestHeaders() fonction. Si un tel tableau associatif est nécessaire, alors la fonction apache est la meilleure option, puisqu'elle retourne exactement les en-têtes reçus au lieu d'une version tronquée en CamelCase. (Notez également qu'à partir de PHP 5.4, elle n'est plus réservée à Apache).

0 votes

Si vous aviez répondu à cette question 2 ans et 11 mois plus tôt, cette réponse aurait eu 200+ upvotes.

0 votes

apache_request_headers() ou getallheaders() ne semble pas mettre en majuscule les noms d'en-tête lorsque je l'ai testé. Ils renvoient exactement ce que je passe du côté client. Alors pourquoi mettez-vous les noms d'en-têtes en majuscules dans une telle fonction de remplacement ?

33voto

Salman A Points 60620

Depuis PHP 5.4.0, vous pouvez utiliser la fonction getallheaders qui renvoie tous les en-têtes de demande sous forme de tableau associatif :

var_dump(getallheaders());

// array(8) {
//   ["Accept"]=>
//   string(63) "text/html[...]"
//   ["Accept-Charset"]=>
//   string(31) "ISSO-8859-1[...]"
//   ["Accept-Encoding"]=>
//   string(17) "gzip,deflate,sdch"
//   ["Accept-Language"]=>
//   string(14) "en-US,en;q=0.8"
//   ["Cache-Control"]=>
//   string(9) "max-age=0"
//   ["Connection"]=>
//   string(10) "keep-alive"
//   ["Host"]=>
//   string(9) "localhost"
//   ["User-Agent"]=>
//   string(108) "Mozilla/5.0 (Windows NT 6.1; WOW64) [...]"
// }

Auparavant, cette fonction ne fonctionnait que lorsque PHP était exécuté en tant que module Apache/NSAPI.

21 votes

Je l'utilise sur PHP-FPM 5.5 et NGINX. getallheaders() n'existe pas.

0 votes

@CMCDragonkai dans FPM comment avez-vous obtenu les informations d'en-tête ?

0 votes

TLFTP ; Si vous utilisez FPM getallheaders() est devenu disponible après la version 7.3

6voto

Glenn Plas Points 685

strtolower fait défaut dans plusieurs des solutions proposées, la RFC2616 (HTTP/1.1) définit les champs d'en-tête comme des entités insensibles à la casse. L'ensemble, et pas seulement le value partie.

Donc les suggestions comme seulement analyser HTTP_ Les entrées sont fausses.

Le mieux serait comme ça :

if (!function_exists('getallheaders')) {
    foreach ($_SERVER as $name => $value) {
        /* RFC2616 (HTTP/1.1) defines header fields as case-insensitive entities. */
        if (strtolower(substr($name, 0, 5)) == 'http_') {
            $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
        }
    }
    $this->request_headers = $headers;
} else {
    $this->request_headers = getallheaders();
}

Notez les différences subtiles avec les suggestions précédentes. La fonction ici fonctionne également sur php-fpm (+nginx).

1 votes

Où exactement la RFC 2616 indique-t-elle que les valeurs des champs sont insensibles à la casse ? Elle indique explicitement que "HTTP-date est sensible à la casse" - et cela va dans la section Date et que "les valeurs des paramètres [texte dans Content-Type après le point-virgule] peuvent être sensibles à la casse ou non". Étant donné qu'il existe au moins deux en-têtes dont les valeurs sont sensibles à la casse, il semble que vous ayez tort.

1 votes

HTTP header fields, which include general-header (section 4.5), request-header (section 5.3), response-header (section 6.2), and entity-header (section 7.1) fields, follow the same generic format as that given in Section 3.1 of RFC 822 [9]. Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive. Donc je suppose que tu as tort.

5 votes

Champ noms sont insensibles à la casse. Il n'y a rien sur le champ valeurs dans ce paragraphe, alors que d'autres parties du document parlent explicitement des valeurs de champs sensibles à la casse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X