Aller au contenu

Superglobales

Lorsqu’une requête HTTP atteint une application PHP, le serveur doit répondre à trois questions :

  1. Que demande le client ?
  2. Quelles données a-t-il envoyées ?
  3. Quelle réponse faut-il produire ?

PHP met une partie de ces informations à disposition dans des tableaux appelés superglobales. Ce chapitre présente les trois principales, puis montre comment répondre non plus à un navigateur, mais à un programme.

Une requête HTTP se compose de plusieurs parties, chacune avec un rôle précis :

  • la ligne de requête : la méthode (l’action demandée), la cible (l’adresse de la ressource et ses paramètres) et la version du protocole ;
  • les en-têtes : des métadonnées sur la requête, comme l’hôte visé, le format du corps ou le format de réponse attendu ;
  • une ligne vide, qui sépare les en-têtes du corps ;
  • un corps facultatif : les données envoyées, par exemple les champs d’un formulaire ou un document JSON.

Une requête POST se présente par exemple ainsi :

POST /index.php?page=commande HTTP/1.1
Host: localhost
Content-Type: application/x-www-form-urlencoded
nom=Ti-Jean&quantite=3

PHP rend ces informations accessibles dans des tableaux disponibles dans tous les fichiers et toutes les fonctions, sans déclaration préalable : les superglobales. Chaque partie de la requête se retrouve ainsi exposée.

Composante de la requêteRôleExposée par PHP dans
MéthodeL’action demandée (GET, POST…).$_SERVER['REQUEST_METHOD']
Cible (URL)La ressource visée et ses paramètres.$_SERVER['REQUEST_URI'], $_GET
En-têtesDes métadonnées sur la requête.$_SERVER (clés HTTP_*)
CorpsLes données envoyées.$_POST, php://input

Ce chapitre détaille les trois superglobales les plus courantes, $_GET, $_POST et $_SERVER, avant d’en présenter quelques autres.

Avant d’examiner chaque superglobale, voici une requête que vous pouvez modifier. Changez la méthode, l’adresse et les champs, puis observez les tableaux que PHP construit à partir de votre requête. Les sections suivantes reprennent ensuite chaque superglobale en détail.

Inspecteur de requête
Modifiez la requête et observez comment PHP remplit les superglobales.
$_GET
[
    "page" => "produits",
    "categorie" => "sirop",
]
$_POST
[]   (vide : la requête n'est pas un POST)
$_SERVER (extrait)
REQUEST_METHOD => "GET"
REQUEST_URI    => "/index.php?page=produits&categorie=sirop"
QUERY_STRING   => "page=produits&categorie=sirop"

Construction. PHP remplit $_GET à partir de la chaîne de requête, c’est-à-dire la portion de l’URL située après le ?. Chaque paramètre s’écrit sous la forme nom=valeur, et le caractère & sépare les paramètres entre eux.

Pour la requête suivante :

Fenêtre de terminal
GET /index.php?page=produits&categorie=sirop

PHP construit le tableau :

<?php
echo $_GET['page']; // "produits"
echo $_GET['categorie']; // "sirop"

Fonctionnement. $_GET est un tableau associatif : chaque clé est le nom d’un paramètre, et chaque valeur est son contenu, toujours sous forme de chaîne de caractères (ou de tableau, voir plus bas).

Usage. On lit une valeur par sa clé, en prévoyant le cas où le paramètre est absent grâce à l’opérateur ?? :

<?php
$categorie = $_GET['categorie'] ?? null;

Une valeur peut aussi être un tableau lorsqu’un paramètre se répète avec la notation [] :

Fenêtre de terminal
GET /index.php?categorie[]=sirop&categorie[]=miel
<?php
$_GET['categorie']; // ["sirop", "miel"]

C’est pourquoi une vérification du type est souvent utile avant d’utiliser la valeur :

<?php
$categorie = $_GET['categorie'] ?? null;
if ($categorie !== null && !is_string($categorie)) {
$categorie = null;
}
$_GET contient les paramètres de l’URL, indépendamment de la méthode HTTP. Une requête POST qui possède une chaîne de requête remplit elle aussi $_GET.

Construction. PHP remplit $_POST à partir du corps d’une requête POST, lorsque ce corps provient d’un formulaire HTML. La clé de chaque valeur est l’attribut name du champ.

<form method="post" action="index.php?page=commande">
<input type="text" name="nom">
<input type="email" name="courriel">
<button>Envoyer</button>
</form>

Après l’envoi, PHP construit :

<?php
echo $_POST['nom']; // la valeur saisie dans le champ « nom »
echo $_POST['courriel']; // la valeur saisie dans le champ « courriel »

Fonctionnement. Comme $_GET, $_POST est un tableau associatif dont les clés sont les noms des champs. Un champ sans attribut name n’apparaît jamais dans $_POST.

Usage. On lit les valeurs de la même façon, avec une valeur par défaut et une validation :

<?php
$nom = trim($_POST['nom'] ?? '');
if ($nom === '') {
// Champ obligatoire manquant.
}
Pour une requête GET, $_POST est vide. C’est la requête POST, et elle seule, qui le remplit à partir de son corps.

Construction. Le serveur web et PHP remplissent $_SERVER avec des informations sur la requête et sur l’environnement d’exécution. À la différence de $_GET et $_POST, ses clés sont prédéfinies : on ne les invente pas, on les consulte.

CléContenu
REQUEST_METHODLa méthode HTTP de la requête (GET, POST…).
REQUEST_URILe chemin demandé, avec la chaîne de requête.
QUERY_STRINGLa chaîne de requête seule, sans le ?.
HTTP_HOSTLe nom d’hôte demandé par le client.
REMOTE_ADDRL’adresse IP du client.

Fonctionnement et usage. On lit une information par sa clé :

<?php
echo $_SERVER['REQUEST_METHOD']; // "GET"
echo $_SERVER['REQUEST_URI']; // "/index.php?page=produits&categorie=sirop"
Certaines valeurs de $_SERVER proviennent du client, comme HTTP_HOST ou les en-têtes transmis par le navigateur. Elles ne sont pas plus fiables que $_GET ou $_POST et doivent être traitées avec la même prudence.

La méthode HTTP, lue dans $_SERVER['REQUEST_METHOD'], indique le type d’action demandé par le client.

MéthodeIntention habituellePropriété importante
GETConsulter une ressource.Sûre et idempotente.
POSTSoumettre des données ou créer une ressource.Généralement non idempotente.
PUTCréer ou remplacer complètement une ressource.Idempotente.
PATCHModifier partiellement une ressource.Pas nécessairement idempotente.
DELETESupprimer une ressource.Idempotente.

On s’en sert pour distinguer l’affichage du traitement dans une même page :

<?php
$methode = $_SERVER['REQUEST_METHOD'];
if ($methode === 'POST') {
// Traiter les données soumises.
} else {
// Afficher la ressource ou le formulaire.
}

Les formulaires HTML prennent directement en charge GET et POST. Les autres méthodes (PUT, PATCH, DELETE) sont généralement envoyées par du JavaScript, une application mobile ou un outil comme curl.

Vérification Une requête POST peut-elle contenir des données dans $_GET ?

Oui. $_GET correspond aux paramètres de la chaîne de requête, pas à la méthode HTTP.

Une requête comme POST /index.php?page=commande place commande dans $_GET['page'], tandis que les champs du formulaire sont placés dans $_POST.

Les trois superglobales précédentes suffisent à la plupart des pages. PHP en fournit cependant d’autres, qu’il est utile de connaître.

Construction. PHP remplit $_REQUEST en fusionnant $_GET, $_POST et $_COOKIE.

Fonctionnement et usage. On y lit une valeur sans se soucier de sa provenance :

<?php
$page = $_REQUEST['page'] ?? 'accueil';

Cette commodité a un revers : l’origine de la donnée devient ambiguë, et deux sources peuvent porter la même clé. Pour la clarté et la sécurité, on désigne plutôt la superglobale précise, $_GET ou $_POST, selon ce que l’on attend.

$_REQUEST mélange plusieurs sources. Préférez $_GET ou $_POST pour savoir exactement d’où provient une donnée.

Construction et fonctionnement. $GLOBALS donne accès à toutes les variables de la portée globale, depuis n’importe quel endroit du code, y compris l’intérieur d’une fonction. C’est la seule superglobale dont le nom ne commence pas par un tiret bas.

<?php
$tva = 0.09975;
function afficherTaux(): void
{
echo $GLOBALS['tva']; // lit la variable globale $tva
}

Usage. Son rôle diffère des autres : il ne concerne pas la requête, mais la portée des variables. On l’évite en pratique, car il contourne l’isolation des fonctions. Passer les valeurs en paramètres, puis les retourner, reste plus clair et plus sûr.

Trois autres superglobales relèvent de sujets à venir. Elles sont mentionnées ici pour compléter la famille.

SuperglobaleRôle
$_SESSIONConserver des données d’une requête à l’autre pour un même visiteur.
$_COOKIELire les témoins déposés dans le navigateur et renvoyés à chaque requête.
$_FILESAccéder aux fichiers téléversés par un formulaire.

Ces trois superglobales seront développées dans un chapitre ultérieur.

Une page renvoie du HTML, ce qui convient à un navigateur dont le rôle est de l’afficher. Le HTML mêle cependant les données et leur présentation : balises de structure, libellés, mise en forme. Un programme qui veut seulement une donnée précise, par exemple le prix d’un produit, devrait alors l’extraire de ce HTML, une opération fragile qui se brise au moindre changement de présentation.

Une API permet de renvoyer les données seules, dans un format prévu pour les programmes. Le format de données JSON est le plus répandu, mais ce n’est pas le seul :

  • le XML, présent dans de nombreux systèmes établis et certains domaines réglementés ;
  • le CSV, commode pour des données tabulaires destinées à un tableur ;
  • le texte brut, pour une réponse simple.

Une même liste de produits prend ainsi plusieurs formes selon le client. Pour un navigateur, du HTML à présenter :

<ul>
<li>Sirop d'érable 540 ml : 14,50 $</li>
<li>Beurre d'érable 250 g : 9,95 $</li>
</ul>

Pour un programme, les mêmes données en JSON :

[
{ "nom": "Sirop d'érable 540 ml", "prix": 14.5 },
{ "nom": "Beurre d'érable 250 g", "prix": 9.95 }
]

Ou en XML, si le client l’attend ainsi :

<produits>
<produit><nom>Sirop d'érable 540 ml</nom><prix>14.50</prix></produit>
<produit><nom>Beurre d'érable 250 g</nom><prix>9.95</prix></produit>
</produits>

Jusqu’ici, une requête GET atteignait une page complète :

Fenêtre de terminal
GET /index.php?page=produits

Le serveur répondait avec toute la page : en-tête, menu, liste des produits, pied de page.

Certains clients ne veulent pas cette page complète, mais demandent le contenu sans la présentation, afin de garder le contrôle sur la mise en forme.

Pour servir une telle requête, plusieurs éléments doivent être réunis :

  1. distinguer cette requête d’une requête de page ordinaire, par une adresse dédiée (un fichier comme api-produits.php, ou une route ?page=api-produits) ;
  2. produire une réponse qui ne contient que les données, sans le gabarit HTML ;
  3. annoncer le format avec l’en-tête Content-Type: application/json ;
  4. encoder les données avec json_encode.

L’exemple d’un tel point d’accès en lecture :

api-produits.php
<?php
$produits = [
["nom" => "Sirop d'érable 540 ml", "prix" => 14.50],
["nom" => "Beurre d'érable 250 g", "prix" => 9.95],
];
header('Content-Type: application/json; charset=utf-8');
echo json_encode($produits, JSON_UNESCAPED_UNICODE);
  1. Programme client vers Serveur PHP : GET (/api-produits.php)
  2. Serveur PHP vers Programme client : 200 · Réponse : un corps JSON
Une requête d'API en lecture

Un programme peut aussi envoyer des données, par exemple pour créer un produit. Il emploie alors la méthode POST. Le corps de la requête arrive de deux façons selon son format :

  • un corps de formulaire, comme celui d’un formulaire HTML, se trouve dans $_POST ;
  • un corps JSON, fréquent entre programmes, se lit avec php://input, puis json_decode le transforme en tableau.

Pour traiter un tel envoi, on vérifie la méthode, on lit et valide les données, puis on répond avec un statut adapté, par exemple 201 Created :

<?php
// api-produits.php (méthode POST)
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$donnees = json_decode(file_get_contents('php://input'), true);
if (!is_array($donnees) || !isset($donnees['nom'], $donnees['prix'])) {
http_response_code(400);
echo json_encode(['erreur' => 'Données invalides']);
exit;
}
// ... enregistrer le produit ...
http_response_code(201);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($donnees, JSON_UNESCAPED_UNICODE);
}

La requête correspondante précise sa méthode, son en-tête de format et son corps :

POST /api-produits.php
Content-Type: application/json
{ "nom": "Tire sur la neige", "prix": 6 }
Un corps JSON n’arrive pas dans $_POST, qui est réservé aux corps de formulaire. On le lit avec php://input, puis on le décode avec json_decode.

Deux autres méthodes complètent l’ensemble. PUT remplace une ressource existante, DELETE la supprime. On les traite comme POST, en consultant $_SERVER['REQUEST_METHOD'] :

<?php
$methode = $_SERVER['REQUEST_METHOD'];
if ($methode === 'PUT') {
// remplacer la ressource visée
} elseif ($methode === 'DELETE') {
// supprimer la ressource visée
}

Un formulaire HTML ne peut émettre que GET et POST. Les requêtes PUT et DELETE proviennent donc d’un programme ou d’un outil de test, présentés plus bas.

Apache, fourni avec XAMPP, traite GET et POST sans réglage particulier, et PHP reçoit PUT et DELETE de la même façon. Deux besoins peuvent toutefois demander une configuration :

  • pour des adresses propres comme /api/produits au lieu de ?page=api-produits, activez le module de réécriture (LoadModule rewrite_module modules/mod_rewrite.so dans httpd.conf) et autorisez les fichiers .htaccess avec AllowOverride All sur le dossier du projet ;
  • pour recevoir un corps volumineux, les directives post_max_size et upload_max_filesize de php.ini fixent la taille acceptée.

Après toute modification de httpd.conf ou de php.ini, redémarrez Apache depuis le panneau de contrôle de XAMPP.

Voici les morceaux précédents réunis en un seul fichier autonome. Déposez-le dans htdocs, sous le nom api-produits.php, et il répond aux requêtes GET et POST. La persistance des données (base de données ou session) viendra plus tard ; ici, la création renvoie simplement le produit reçu.

<?php
// api-produits.php, un point d'accès d'API minimal et complet.
header('Content-Type: application/json; charset=utf-8');
// Données de départ (plus tard : une base de données).
$produits = [
["nom" => "Sirop d'érable 540 ml", "prix" => 14.50],
["nom" => "Beurre d'érable 250 g", "prix" => 9.95],
["nom" => "Tire sur la neige", "prix" => 6.00],
];
$methode = $_SERVER['REQUEST_METHOD'];
if ($methode === 'GET') {
// Lire : renvoyer la liste des produits.
echo json_encode($produits, JSON_UNESCAPED_UNICODE);
exit;
}
if ($methode === 'POST') {
// Créer : lire le corps JSON, valider, répondre.
$donnees = json_decode(file_get_contents('php://input'), true);
if (!is_array($donnees) || !isset($donnees['nom'], $donnees['prix'])) {
http_response_code(400); // 400 Bad Request
echo json_encode(['erreur' => 'Le nom et le prix sont requis.']);
exit;
}
$nouveau = [
'nom' => (string) $donnees['nom'],
'prix' => (float) $donnees['prix'],
];
http_response_code(201); // 201 Created
echo json_encode($nouveau, JSON_UNESCAPED_UNICODE);
exit;
}
// Toute autre méthode n'est pas prise en charge.
http_response_code(405); // 405 Method Not Allowed
echo json_encode(['erreur' => "Méthode $methode non prise en charge."]);

Une fois le fichier en place, la lecture s’obtient avec une requête GET, et la création avec une requête POST accompagnée d’un corps JSON. La sous-section suivante montre comment envoyer ces deux requêtes.

Bruno et Postman sont des clients d’API qui permettent de composer une requête (méthode, adresse, en-têtes, corps) et examiner la réponse (statut, en-têtes, corps) sans écrire de code.

  • Postman est très répandu et conserve les requêtes dans un espace de travail, souvent partagé en ligne.
  • Bruno est léger et ouvert ; il enregistre les requêtes dans des fichiers locaux, faciles à versionner avec le code du projet.

Pour tester l’API des produits avec l’un de ces outils, une requête GET vers http://localhost/api-produits.php affiche la réponse JSON. Une requête POST vers la même adresse, avec l’en-tête Content-Type: application/json et un corps JSON, crée un produit.

  • $_GET contient les paramètres de la chaîne de requête, quelle que soit la méthode HTTP.
  • $_POST contient les données des formulaires envoyés avec POST ; il est vide pour une requête GET.
  • $_SERVER contient des informations sur la requête et l’environnement, avec des clés prédéfinies comme REQUEST_METHOD.
  • Toute donnée provenant du client doit être validée avant son utilisation, puis échappée à l’affichage.
  • Une API renvoie les données seules, sans la présentation HTML, dans un format prévu pour les programmes : le JSON le plus souvent, parfois le XML ou le CSV.
  • On distingue une requête d’API par sa route et sa méthode ; un corps JSON se lit avec php://input, et non avec $_POST.
  • GET consulte, POST envoie, PUT remplace et DELETE supprime ; des outils comme Bruno, Postman ou curl permettent de tester ces requêtes.

Quiz. Quelle superglobale contient la méthode HTTP de la requête ?

Quiz. Une requête POST contient ?categorie=sirop dans son URL. Où PHP place-t-il cette valeur ?

Quiz. Quelle superglobale contient les champs d'un formulaire envoyé avec la méthode POST ?

Quiz. Comment répondre en JSON à un programme plutôt qu'en HTML ?