Formulaires et validation
Jusqu’ici, les pages produisaient du contenu. Avec les formulaires, le visiteur envoie à son tour des données au serveur : un message de contact, une recherche, une inscription. Ce chapitre suit ce trajet de bout en bout : envoyer, récupérer, valider, puis afficher sans danger.
Rappel : méthodes HTTP et communication client-serveur
Section intitulée « Rappel : méthodes HTTP et communication client-serveur »Chaque requête HTTP porte une méthode qui annonce l’intention du client. Deux nous occupent ici :
GETdemande une ressource (lire une page, une recherche).POSTenvoie des données au serveur pour qu’il les traite (un message, une création).
Soumettre un formulaire, c’est donc déclencher une nouvelle requête, exactement le cycle vu au chapitre Introduction, mais cette fois la requête transporte les données saisies.
- Client (navigateur) vers Serveur (Apache + PHP) : Requête POST (POST /contact.php (+ données))
- Serveur (Apache + PHP) : Récupère et valide les données
- Serveur (Apache + PHP) vers Client (navigateur) : 200 · Réponse : HTML (confirmation ou erreurs)
Envoyer des données : GET et POST
Section intitulée « Envoyer des données : GET et POST »Côté navigateur, c’est la balise <form> qui prépare l’envoi. Deux attributs comptent : action (l’URL qui recevra la requête) et method (get ou post).
<form action="contact.php" method="post"> <label>Nom <input type="text" name="nom"></label> <label>Courriel <input type="email" name="courriel"></label> <label>Message <textarea name="message"></textarea></label> <button type="submit">Envoyer</button></form>L’attribut name de chaque champ est essentiel : c’est lui qui devient la clé sous laquelle PHP retrouvera la valeur. Un champ sans name n’est jamais transmis.
La méthode change l’endroit où voyagent les données :
- Avec
GET, elles partent dans l’URL, à la suite d’un?:produits.php?q=sirop. Visibles, partageables, mais limitées en taille — parfait pour une recherche ou un filtre. - Avec
POST, elles partent dans le corps de la requête, hors de l’URL — adapté à l’envoi d’un message, d’un mot de passe, d’un fichier.
<!-- Une recherche : GET, car on ne fait que lire --><form action="produits.php" method="get"> <input type="search" name="q" placeholder="Rechercher un produit"> <button type="submit">Chercher</button></form>Récupérer les données : $_GET et $_POST
Section intitulée « Récupérer les données : $_GET et $_POST »Côté serveur, PHP dépose les données reçues dans deux superglobales, des tableaux associatifs accessibles partout : $_GET pour les données d’URL, $_POST pour celles du corps. La clé est le name du champ.
<?php$nom = $_POST["nom"] ?? "";$courriel = $_POST["courriel"] ?? "";$message = $_POST["message"] ?? "";On distingue souvent le premier affichage du formulaire de son traitement en testant la méthode de la requête :
<?phpif ($_SERVER["REQUEST_METHOD"] === "POST") { // Le formulaire a été soumis : on récupère et on traite. $nom = $_POST["nom"] ?? "";}Valider les données côté serveur
Section intitulée « Valider les données côté serveur »Une donnée qui arrive du client n’est jamais fiable : un champ peut être vide, mal rempli, ou trafiqué en contournant le navigateur. Toute validation qui compte doit se faire côté serveur. La validation HTML (required, type="email") améliore le confort, mais se désactive en deux clics : elle ne protège rien.
La démarche habituelle : rassembler les erreurs dans un tableau, puis ne traiter que si ce tableau est vide.
<?php$erreurs = [];
$nom = trim($_POST["nom"] ?? "");$courriel = trim($_POST["courriel"] ?? "");$message = trim($_POST["message"] ?? "");
if ($nom === "") { $erreurs[] = "Le nom est obligatoire.";}
if (!filter_var($courriel, FILTER_VALIDATE_EMAIL)) { $erreurs[] = "Le courriel n'est pas valide.";}
if (mb_strlen($message) < 10) { $erreurs[] = "Le message doit contenir au moins 10 caractères.";}
if (empty($erreurs)) { // Les données sont valides : on les enregistre, on envoie le courriel, etc. echo "Merci, votre message a bien été reçu.";}Quand des erreurs existent, on réaffiche le formulaire avec les messages — et en conservant ce que la personne avait déjà saisi, pour ne pas la forcer à tout retaper.
-
Si le tableau
$erreursn’est pas vide, on les liste au-dessus du formulaire :<?php foreach ($erreurs as $erreur): ?><p class="erreur"><?php echo htmlspecialchars($erreur); ?></p><?php endforeach; ?> -
On repré-remplit chaque champ avec la valeur reçue, échappée :
<input type="text" name="nom"value="<?php echo htmlspecialchars($nom); ?>">
Ouverture sur les API
Section intitulée « Ouverture sur les API »Un formulaire n’est qu’une façon, parmi d’autres, d’envoyer des données. Une API reçoit des requêtes émises non par un navigateur, mais par un autre programme (application mobile, autre serveur, code JavaScript). Le principe reste le même — une requête, une méthode, une réponse — mais les données échangées sont généralement du JSON plutôt que du HTML.
<?php// Au lieu de renvoyer du HTML, on renvoie du JSON.header("Content-Type: application/json");echo json_encode(["statut" => "ok", "message" => "Reçu"]);<?php// Et on lit un corps JSON envoyé par le client (au lieu de $_POST).$donnees = json_decode(file_get_contents("php://input"), true);Sécurité de l’affichage : htmlspecialchars
Section intitulée « Sécurité de l’affichage : htmlspecialchars »La validation protège l’entrée. Il reste à protéger la sortie. Afficher tel quel un texte fourni par l’utilisateur ouvre la porte à une attaque par injection : si quelqu’un saisit comme nom une balise <script>, elle s’exécutera dans le navigateur de tous ceux qui verront la page. C’est une faille XSS (cross-site scripting).
<?php// DANGEREUX : la saisie est insérée telle quelle dans la page.echo "Bonjour " . $_GET["nom"];La parade est systématique : htmlspecialchars() convertit les caractères dangereux (<, >, &, ") en entités HTML inoffensives. La balise s’affiche alors comme du texte, sans s’exécuter.
<?php// SÛR : la saisie est échappée avant l'affichage.echo "Bonjour " . htmlspecialchars($_GET["nom"]);Échappez avec htmlspecialchars() tout ce qui provient de l’utilisateur, au moment de l’afficher — dans le corps de la page comme dans les attributs (value="..."). C’est le même réflexe que pour les fragments réutilisés, vu au chapitre Navigation et composition.
Vérification Pourquoi valider côté serveur si le formulaire a déjà des attributs required et type='email' ?
Parce que la validation HTML s’exécute dans le navigateur, où elle peut être désactivée ou contournée (en envoyant la requête directement, sans passer par le formulaire). Le serveur est le seul endroit que le client ne contrôle pas : c’est là que la validation doit avoir lieu pour de bon.
Récapitulatif
Section intitulée « Récapitulatif »- Soumettre un formulaire déclenche une requête HTTP :
GETpour lire (données dans l’URL),POSTpour envoyer (données dans le corps). - L’attribut
namede chaque champ devient la clé dans$_GETou$_POST;??gère l’absence de valeur. - La validation côté serveur est la seule qui compte : rassemblez les erreurs, ne traitez que si elles sont absentes, et réaffichez la saisie en cas d’échec.
- Une API reçoit les mêmes requêtes en JSON : même discipline de validation.
- À l’affichage,
htmlspecialchars()sur toute donnée venue de l’utilisateur évite les failles XSS.
Quiz. Quelle méthode pour envoyer un message de contact à enregistrer ?
Quiz. Sous quelle clé PHP retrouve-t-il la valeur de <input name='courriel'> envoyé en POST ?
Quiz. À quoi sert htmlspecialchars() ?
Quiz. Pourquoi ne pas se fier à la validation HTML (required, type='email') seule ?