Traitement des formulaires PHP : guide complet
Apprenez à traiter les formulaires en PHP : lecture des données, validation côté serveur, protection XSS et injections SQL.
La gestion des formulaires est l'une des tâches les plus courantes dans toute application web : une page d'inscription, un formulaire de contact, un champ de recherche ou un tunnel de commande envoient tous des données utilisateur au serveur, où PHP les lit, les contrôle et agit en conséquence. Ce guide décrit le cycle complet — du formulaire HTML dans le navigateur jusqu'au PHP qui reçoit, valide et réutilise en toute sécurité les données soumises.
À la fin, vous comprendrez comment $_POST et $_GET fonctionnent, comment valider les données côté serveur, comment garder le formulaire « persistant » après une erreur, et comment éviter les deux failles de sécurité classiques (XSS et injection SQL).
Comment fonctionne la soumission d'un formulaire
La soumission d'un formulaire est une simple requête HTTP envoyée par le navigateur au serveur :
- L'utilisateur remplit les champs et clique sur Envoyer.
- Le navigateur regroupe les valeurs des champs selon la
methoddu formulaire et les envoie à l'URL indiquée dans l'attributaction. - PHP sur le serveur reçoit les valeurs dans un tableau superglobal —
$_POSTou$_GET— et votre script les traite.
Les données provenant du navigateur de l'utilisateur, vous ne pouvez jamais leur faire confiance. N'importe qui peut modifier les valeurs des champs, supprimer des champs ou envoyer la requête sans passer par votre formulaire. La validation côté serveur n'est donc pas optionnelle — les attributs required et type="email" côté client ne sont qu'une commodité.
Créer un formulaire HTML
Tout formulaire commence en HTML. Il contient des champs de saisie — zones de texte, champs e-mail, boutons radio, cases à cocher — et un bouton d'envoi. Deux attributs pilotent tout :
action— l'URL qui reçoit les données (omettez-le pour renvoyer les données à la même page).method—postouget(voir la comparaison ci-dessous).
<form action="form_processing.php" method="post">
<p>
<label for="name">Name:</label>
<input type="text" id="name" name="name" />
</p>
<p>
<label for="email">Email:</label>
<input type="email" id="email" name="email" />
</p>
<input type="submit" value="Submit" />
</form>L'attribut name de chaque champ est la clé que vous lisez côté serveur : name="email" devient $_POST['email']. Un champ sans name n'est jamais soumis. Associez toujours chaque champ à un <label> pour l'accessibilité.
POST vs. GET
L'attribut method détermine comment les données transitent et quel tableau les reçoit.
method="post" | method="get" | |
|---|---|---|
| Emplacement des données | Corps de la requête HTTP | Ajouté à l'URL sous forme de chaîne de requête |
| Tableau PHP | $_POST | $_GET |
| Visible dans l'URL | Non | Oui (?name=Ann&email=...) |
| Peut être mis en favori / partagé | Non | Oui |
| Adapté pour | Mots de passe, toute modification de données | Filtres de recherche, pagination — requêtes en lecture seule |
Utilisez POST pour tout ce qui crée, modifie ou supprime des données, ou qui contient des valeurs sensibles. Utilisez GET pour les recherches et filtres que vous souhaitez que les utilisateurs puissent mettre en favori. Les deux arrivent dans le superglobal correspondant ; le reste de ce guide utilise POST.
Lire les données soumises
Lorsque le formulaire est envoyé, PHP remplit $_POST avec les noms des champs comme clés et le texte soumis comme valeurs. Lisez chaque champ, mais protégez-vous contre les clés manquantes avec l'opérateur de fusion null ?? afin qu'un champ absent renvoie une chaîne vide plutôt qu'un avertissement :
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';Vérifiez $_SERVER['REQUEST_METHOD'] pour que le code de traitement ne s'exécute que lors d'une vraie soumission, et non à la première ouverture de la page :
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = $_POST['name'] ?? '';
$email = $_POST['email'] ?? '';
// ...validate and use the values
}Valider les données
La validation répond à une seule question : cette valeur est-elle acceptable ? Collectez chaque problème dans un tableau $errors afin de montrer à l'utilisateur toutes les erreurs à la fois, au lieu de s'arrêter à la première. Utilisez filter_var() avec FILTER_VALIDATE_EMAIL pour vérifier correctement le format de l'e-mail :
$errors = [];
if (trim($name) === '') {
$errors[] = "Name is required";
}
if (trim($email) === '') {
$errors[] = "Email is required";
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = "Invalid email format";
}
if (!empty($errors)) {
foreach ($errors as $error) {
echo htmlspecialchars($error) . "<br>";
}
}Nous utilisons trim() pour qu'un champ ne contenant que des espaces soit considéré comme vide, puis filter_var() pour confirmer que l'e-mail ressemble à [email protected]. Si $errors n'est pas vide, les messages sont affichés ; sinon, les données sont propres et prêtes à l'emploi. Pour une couverture plus approfondie des champs obligatoires et des règles e-mail/URL, consultez Validation des formulaires PHP et Validation des champs obligatoires.
Échappement des sorties : prévenir le XSS
Remarquez l'appel à htmlspecialchars() ci-dessus. Chaque fois que vous affichez une valeur provenant de l'utilisateur, vous devez l'échapper, sinon un attaquant peut soumettre des balises <script> qui s'exécutent dans le navigateur des autres visiteurs — c'est une attaque de type cross-site scripting (XSS). htmlspecialchars() convertit <, >, & et les guillemets en entités HTML inoffensives :
$dangerous = '<script>alert("xss")</script>';
echo htmlspecialchars($dangerous);
// <script>alert("xss")</script>Le navigateur affiche désormais le texte littéralement au lieu de l'exécuter. Échappez à la sortie, à chaque fois.
Garder le formulaire persistant
Si la validation échoue, réaffichez le formulaire avec les valeurs de l'utilisateur déjà renseignées — devoir tout ressaisir est frustrant. Renvoyez chaque valeur dans son attribut value, après échappement :
<input
type="text"
name="name"
value="<?php echo htmlspecialchars($name ?? ''); ?>"
/>Comme la même page rend le formulaire et le traite, définissez action="" (renvoyer à elle-même) et le champ se repopule automatiquement après un envoi échoué.
Tout assembler
Voici une page auto-traitante qui rend le formulaire, valide lors d'un POST, affiche les erreurs, garde le formulaire persistant et confirme le succès — le schéma que suivent la plupart des vrais formulaires de contact :
<?php
$name = $email = '';
$errors = [];
$success = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
if ($name === '') {
$errors[] = 'Name is required';
}
if ($email === '') {
$errors[] = 'Email is required';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = 'Invalid email format';
}
if (!$errors) {
$success = true; // here you would save to a database or send an email
}
}
?>
<?php if ($success): ?>
<p>Thanks, <?php echo htmlspecialchars($name); ?>!</p>
<?php else: ?>
<?php foreach ($errors as $e): ?>
<p style="color:red"><?php echo htmlspecialchars($e); ?></p>
<?php endforeach; ?>
<form action="" method="post">
Name:
<input type="text" name="name"
value="<?php echo htmlspecialchars($name); ?>"><br>
Email:
<input type="email" name="email"
value="<?php echo htmlspecialchars($email); ?>"><br>
<input type="submit" value="Submit">
</form>
<?php endif; ?>Stocker les données en toute sécurité : prévenir l'injection SQL
Une fois les données valides, vous les enregistrez souvent dans une base de données. Ne jamais insérer directement des données utilisateur dans une chaîne SQL — cela ouvre la porte à l'injection SQL. Utilisez une requête préparée pour que la base de données traite les valeurs comme des données, jamais comme des commandes :
$mysqli = new mysqli('localhost', 'user', 'pass', 'app');
$stmt = $mysqli->prepare(
'INSERT INTO contacts (name, email) VALUES (?, ?)'
);
$stmt->bind_param('ss', $name, $email);
$stmt->execute();Les espaces réservés ? et bind_param() maintiennent les valeurs séparées de la requête, de sorte qu'une entrée comme '; DROP TABLE contacts; -- est stockée comme du texte inoffensif au lieu d'être exécutée.
Liste de contrôle de sécurité
Un script de traitement de formulaire sécurisé suit une routine courte et reproductible :
- Validez chaque champ côté serveur — ne vous fiez jamais aux seules vérifications du navigateur.
- Échappez à la sortie avec
htmlspecialchars()pour stopper le XSS. - Utilisez des requêtes préparées pour chaque requête de base de données afin de stopper l'injection SQL.
- Hachez les mots de passe avec
password_hash()avant de les stocker — ne stockez jamais du texte en clair. - Ajoutez un token CSRF aux formulaires qui modifient des données pour éviter les requêtes forgées depuis d'autres sites.
- Ajoutez un CAPTCHA aux formulaires publics pour réduire les soumissions automatisées de spam.
Chapitres connexes
- Gestion des formulaires PHP — les bases de la réception des données de formulaire.
- PHP $_POST — le superglobal en détail.
- Validation des formulaires PHP — schémas de validation complets.
- Superglobaux PHP —
$_POST,$_GET,$_SERVER, et bien d'autres.