Du formulaire HTML au traitement PHP
Voici le flux complet quand un utilisateur soumet un formulaire :
- L'utilisateur remplit le formulaire HTML et clique sur « Envoyer »
- Le navigateur envoie les données au serveur (via GET ou POST)
- PHP récupère les données dans
$_GETou$_POST - PHP traite, valide et répond
<!-- Le formulaire HTML -->
<form action="traitement.php" method="POST">
<label>Votre nom :</label>
<input type="text" name="nom">
<label>Votre email :</label>
<input type="email" name="email">
<button type="submit">Envoyer</button>
</form>
// traitement.php
$nom = $_POST['nom'];
$email = $_POST['email'];
echo "Merci $nom, nous vous contacterons à $email.";
D'abord : les superglobales
Avant de parler de GET et POST, il faut connaître la famille à laquelle ils appartiennent : les superglobales. Ce sont des tableaux que PHP remplit tout seul à chaque requête, et qui sont accessibles partout dans ton code (même à l'intérieur d'une fonction, sans avoir à écrire global). C'est par elles que les données du monde extérieur (le navigateur, le serveur) entrent dans ton programme.
Les principales :
$_GET: les données passées dans l'URL (après le?).$_POST: les données envoyées dans le corps d'une requête POST (formulaires).$_REQUEST: un mélange de$_GET,$_POSTet$_COOKIE. Pratique mais ambigu : mieux vaut viser directement le bon tableau.$_SERVER: des infos sur la requête et le serveur (méthode HTTP, URL, en-têtes, IP du visiteur…).$_SESSION: les données mémorisées entre les pages pour un visiteur (panier, connexion).$_COOKIE: les cookies renvoyés par le navigateur.$_FILES: les fichiers envoyés (upload).$_ENV: les variables d'environnement du serveur.$GLOBALS: toutes les variables globales du script.
On s'en sert comme de n'importe quel tableau associatif : $_POST['email'], $_SERVER['REQUEST_METHOD'], $_SESSION['user']. Pas besoin de les déclarer ni de les importer : elles sont toujours là.
Celles qui transportent des données venues du visiteur ($_GET, $_POST, $_REQUEST, $_COOKIE, $_FILES) ne sont jamais fiables : n'importe qui peut envoyer n'importe quoi. On valide systématiquement à l'entrée et on échappe à l'affichage (on y revient plus bas). À l'inverse, $_SESSION vit côté serveur : elle, on la contrôle.
Les deux que tu croiseras le plus, et de loin, ce sont $_GET et $_POST. Regardons-les de près.
$_GET vs $_POST
Les deux méthodes pour envoyer des données :
- GET : données visibles dans l'URL :
page.php?q=php&page=2 - POST : données invisibles (dans le corps de la requête)
Un formulaire de connexion envoie un identifiant et un mot de passe. Avant de dérouler : quelle est la vraie différence entre envoyer ces champs en $_GET et en $_POST ? Où se retrouvent les données dans chaque cas ? Et peut-on dire que $_POST est « sécurisé » parce que les données ne sont pas dans l'URL ?
Voir la réponse
Avec GET, les données sont collées dans l'URL (?login=alice&pwd=…) : visibles dans la barre d'adresse, enregistrées dans l'historique du navigateur et les logs serveur, mémorisables en favori, et de taille limitée. Avec POST, elles voyagent dans le corps de la requête, donc absentes de l'URL. Mais attention : POST n'est pas « sécurisé » pour autant. Le corps d'une requête POST circule en clair, tout aussi lisible et modifiable par l'utilisateur (via les outils du navigateur ou un proxy). Seul HTTPS chiffre la communication. La règle : GET pour récupérer ou naviguer (recherche, filtre, lien partageable), POST pour les actions qui changent l'état (créer, modifier, envoyer un formulaire) ; et ne jamais faire confiance à l'un ni à l'autre : toute donnée venant du client doit être validée côté serveur.
// GET : pour les recherches, filtres, pagination
// URL : recherche.php?q=php&page=2
$recherche = $_GET['q']; // "php"
$page = $_GET['page']; // "2"
// POST : pour les formulaires sensibles (login, contact, paiement)
$email = $_POST['email'];
$password = $_POST['password'];
Règle : utilisez POST pour tout ce qui modifie des données ou contient des informations sensibles. GET uniquement pour lire/rechercher.
Validation des données
Règle d'or : ne jamais faire confiance aux données utilisateur. Un utilisateur (ou un bot) peut envoyer n'importe quoi.
// Vérifier que le champ existe et n'est pas vide
if (empty($_POST['nom'])) {
$erreur = "Le nom est obligatoire.";
}
// Valider un email
$email = $_POST['email'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$erreur = "Email invalide.";
}
// Nettoyer les données contre le XSS
$nom = htmlspecialchars($_POST['nom'], ENT_QUOTES, 'UTF-8');
// Transforme <script>alert('hack')</script>
// en <script>alert('hack')</script>
htmlspecialchars() est ton bouclier contre les attaques XSS (Cross-Site Scripting). Utilise-le chaque fois que tu affiches des données saisies par un utilisateur.
Exemple complet : formulaire de contact
<?php
$erreurs = [];
$succes = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 1. Récupérer et nettoyer
$nom = htmlspecialchars(trim($_POST['nom'] ?? ''), ENT_QUOTES, 'UTF-8');
$email = trim($_POST['email'] ?? '');
$msg = htmlspecialchars(trim($_POST['message'] ?? ''), ENT_QUOTES, 'UTF-8');
// 2. Valider
if (empty($nom)) $erreurs[] = "Le nom est obligatoire.";
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $erreurs[] = "Email invalide.";
if (strlen($msg) < 10) $erreurs[] = "Message trop court (min 10 caractères).";
// 3. Traiter si pas d'erreurs
if (empty($erreurs)) {
// Envoyer un email, sauvegarder en BDD, etc.
$succes = true;
}
}
?>
<?php if ($succes): ?>
<p class="success">Merci <?= $nom ?>, message envoyé !</p>
<?php else: ?>
<?php foreach ($erreurs as $e): ?>
<p class="error"><?= $e ?></p>
<?php endforeach; ?>
<form method="POST">
<input name="nom" value="<?= $nom ?? '' ?>" placeholder="Nom">
<input name="email" value="<?= $email ?? '' ?>" placeholder="Email">
<textarea name="message"><?= $msg ?? '' ?></textarea>
<button>Envoyer</button>
</form>
<?php endif; ?>
Sécurité : ne jamais faire confiance
Résumé des bonnes pratiques :
htmlspecialchars(): contre le XSS, à chaque affichagefilter_var(): pour valider emails, URLs, nombrestrim(): supprimer les espaces parasitesempty(): vérifier qu'un champ n'est pas vide- Requêtes préparées : contre l'injection SQL (leçon 6)
From HTML form to PHP processing
Here's the full flow when a user submits a form:
- The user fills in the HTML form and clicks "Submit"
- The browser sends the data to the server (via GET or POST)
- PHP retrieves the data in
$_GETor$_POST - PHP processes, validates and responds
<!-- The HTML form -->
<form action="process.php" method="POST">
<label>Your name:</label>
<input type="text" name="name">
<label>Your email:</label>
<input type="email" name="email">
<button type="submit">Submit</button>
</form>
// process.php
$name = $_POST['name'];
$email = $_POST['email'];
echo "Thanks $name, we'll contact you at $email.";
First: the superglobals
Before talking about GET and POST, you need to know the family they belong to: the superglobals. These are arrays that PHP fills automatically on every request, and that are accessible everywhere in your code (even inside a function, without writing global). They're how data from the outside world (the browser, the server) enters your program.
The main ones:
$_GET— data passed in the URL (after the?).$_POST— data sent in the body of a POST request (forms).$_REQUEST— a mix of$_GET,$_POSTand$_COOKIE. Handy but ambiguous: better to target the right array directly.$_SERVER— info about the request and the server (HTTP method, URL, headers, visitor IP…).$_SESSION— data remembered across pages for a visitor (cart, login).$_COOKIE— the cookies sent back by the browser.$_FILES— the files uploaded.$_ENV— the server's environment variables.$GLOBALS— all the script's global variables.
You use them like any associative array: $_POST['email'], $_SERVER['REQUEST_METHOD'], $_SESSION['user']. No need to declare or import them: they're always there.
The ones carrying data from the visitor ($_GET, $_POST, $_REQUEST, $_COOKIE, $_FILES) are never trustworthy: anyone can send anything. You validate systematically on the way in and escape on the way out (more below). Conversely, $_SESSION lives on the server: that one you control.
The two you'll meet by far the most are $_GET and $_POST. Let's look at them closely.
$_GET vs $_POST
Two methods to send data:
- GET — data visible in the URL:
page.php?q=php&page=2 - POST — data invisible (in the request body)
A login form sends a username and a password. Before scrolling down: what is the real difference between sending those fields via $_GET and via $_POST? Where does the data end up in each case? And can you say that $_POST is "secure" because the data is not in the URL?
See the answer
With GET, the data is appended to the URL (?login=alice&pwd=…): visible in the address bar, recorded in the browser history and server logs, bookmarkable, and size-limited. With POST, it travels in the request body, so it is absent from the URL. But beware: POST is not “secure” for that reason. The body of a POST request travels in plain text, just as readable and modifiable by the user (via browser dev tools or a proxy). Only HTTPS encrypts the communication. The rule: GET for retrieving or navigating (search, filter, shareable link), POST for actions that change state (create, modify, submit a form); and never trust either one: any data coming from the client must be validated server-side.
// GET — for searches, filters, pagination
// URL: search.php?q=php&page=2
$search = $_GET['q']; // "php"
$page = $_GET['page']; // "2"
// POST — for sensitive forms (login, contact, payment)
$email = $_POST['email'];
$password = $_POST['password'];
Rule: use POST for anything that modifies data or contains sensitive info. GET only for reading/searching.
Data validation
Golden rule: never trust user data. A user (or a bot) can send anything.
// Check that the field exists and isn't empty
if (empty($_POST['name'])) {
$error = "Name is required.";
}
// Validate an email
$email = $_POST['email'];
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error = "Invalid email.";
}
// Sanitize data against XSS
$name = htmlspecialchars($_POST['name'], ENT_QUOTES, 'UTF-8');
// Transforms <script>alert('hack')</script>
// into <script>alert('hack')</script>
htmlspecialchars() is your shield against XSS attacks (Cross-Site Scripting). Use it every time you display user-entered data.
Complete example: contact form
<?php
$errors = [];
$success = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 1. Retrieve and sanitize
$name = htmlspecialchars(trim($_POST['name'] ?? ''), ENT_QUOTES, 'UTF-8');
$email = trim($_POST['email'] ?? '');
$msg = htmlspecialchars(trim($_POST['message'] ?? ''), ENT_QUOTES, 'UTF-8');
// 2. Validate
if (empty($name)) $errors[] = "Name is required.";
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = "Invalid email.";
if (strlen($msg) < 10) $errors[] = "Message too short (min 10 characters).";
// 3. Process if no errors
if (empty($errors)) {
// Send email, save to DB, etc.
$success = true;
}
}
?>
<?php if ($success): ?>
<p class="success">Thanks <?= $name ?>, message sent!</p>
<?php else: ?>
<?php foreach ($errors as $e): ?>
<p class="error"><?= $e ?></p>
<?php endforeach; ?>
<form method="POST">
<input name="name" value="<?= $name ?? '' ?>" placeholder="Name">
<input name="email" value="<?= $email ?? '' ?>" placeholder="Email">
<textarea name="message"><?= $msg ?? '' ?></textarea>
<button>Submit</button>
</form>
<?php endif; ?>
Security: never trust input
Summary of best practices:
htmlspecialchars()— against XSS, on every outputfilter_var()— to validate emails, URLs, numberstrim()— remove trailing whitespaceempty()— check that a field is not empty- Prepared statements — against SQL injection (lesson 6)
À vous d'essayer (vrai PHP)
On simule un envoi de formulaire avec un tableau $donnees (comme $_POST), on valide, puis on affiche en sécurisant avec htmlspecialchars. Modifie les données, puis clique sur « Run » :
<?php
// En vrai, ces données viendraient de $_POST. On les simule ici.
$donnees = [
'nom' => 'Alice',
'email' => 'alice@exemple.fr',
];
$erreurs = [];
// Validation
$nom = trim($donnees['nom'] ?? '');
$email = trim($donnees['email'] ?? '');
if ($nom === '') $erreurs[] = "Le nom est obligatoire.";
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $erreurs[] = "Email invalide.";
// Résultat
if ($erreurs) {
foreach ($erreurs as $erreur) {
echo "Erreur : $erreur\n";
}
} else {
echo "Merci $nom ! Message envoyé à $email.\n";
// Et SI on réaffiche un nom dans une PAGE HTML, on l'échappe (anti-XSS).
// htmlspecialchars transforme les balises en texte inoffensif :
$dangereux = 'Bob <script>alert(1)</script>';
echo "\nÉchappé pour le HTML : " . htmlspecialchars($dangereux, ENT_QUOTES, 'UTF-8') . "\n";
}
?>
🎯 Pratique
S'entraîner (clique pour ouvrir) :
✨ Prompt IA
Copiez ce prompt dans Claude ou ChatGPT :
Crée un formulaire d'inscription PHP complet avec validation : nom, email, mot de passe (min 8 caractères), confirmation du mot de passe. Affiche les erreurs au-dessus du formulaire et pré-remplit les champs en cas d'erreur.
💬 Ré-explique sans regarder
L'IA t'a écrit un formulaire d'inscription avec validation. Sans le relire : pourquoi faut-il valider en PHP côté serveur alors que le navigateur fait déjà des vérifications (required, type="email") ?
curl ou Postman) et viser directement ton traitement.php. Le serveur est le seul endroit que l'attaquant ne contrôle pas : c'est donc le seul endroit où la validation est réelle. filter_var(..., FILTER_VALIDATE_EMAIL) et empty() côté PHP sont la vraie barrière ; le HTML n'est qu'une aide pour l'utilisateur honnête.⚖️ Juge le code de l'IA
L'IA te propose ce traitement de recherche. Ton rôle de relecteur : l'accepter tel quel ou le rejeter, et dire pourquoi.
<?php
$q = $_GET['q'];
echo "<h1>Résultats pour : $q</h1>";
?>
$_GET['q'] vient du visiteur et est réaffiché tel quel dans le HTML. Une URL comme ?q=<script>…</script> exécuterait le script dans le navigateur de la victime. Le réflexe pro : échapper à l'affichage avec htmlspecialchars($q, ENT_QUOTES, 'UTF-8'), et au passage gérer le cas où q n'existe pas ($_GET['q'] ?? '') pour éviter le warning. Le code « marche » sur un test gentil, mais il est exploitable : c'est exactement le genre de ligne qu'il ne faut jamais laisser passer.🧠 Rappel libre
Sans remonter dans la leçon : quand choisis-tu $_POST plutôt que $_GET, et à quoi sert htmlspecialchars() ?
$_GET met les données dans l'URL (recherches, filtres, pagination : rien de sensible, c'est partageable et mis en cache). $_POST les met dans le corps de la requête : on l'utilise dès qu'on modifie des données ou qu'il y a du sensible (login, contact, paiement). htmlspecialchars() transforme les caractères HTML (<, >, ", &) en entités : c'est le bouclier anti-XSS, à appliquer à chaque fois qu'on réaffiche une donnée venue de l'utilisateur.$_GET pour l'URL page.php?id=42 ?Un formulaire récupère bien une donnée, mais PHP l'oublie dès la page suivante. Comment garder un visiteur connecté de page en page ? Direction les sessions et les cookies, la mémoire qui survit au rechargement.
Leçon 6 : Sessions et cookies →