Sous-solP PHPPièce 5/7Intermédiaire

Formulaires et sécurité

Recevoir les données d'un formulaire avec $_GET et $_POST, les valider et protéger l'affichage contre les failles XSS avec htmlspecialchars.

Ce que tu vas apprendre

  • Lire les données envoyées par un formulaire avec $_GET et $_POST.
  • Valider ces données avant de les utiliser.
  • Neutraliser le HTML malveillant avec htmlspecialchars pour éviter une faille XSS.

Un formulaire HTML

Voici un formulaire pour ajouter une recette. L'attribut method choisit comment les données voyagent.

ajouter.php
<form method="post" action="ajouter.php">
  <label>Titre <input type="text" name="titre"></label>
  <label>Durée <input type="number" name="duree"></label>
  <button type="submit">Ajouter</button>
</form>

Le champ name de chaque input devient la clé sous laquelle PHP retrouve la valeur.

GET et POST

PHP range les données reçues dans des tableaux spéciaux, les superglobales, disponibles partout.

SuperglobaleOrigineUsage typique
$_GETl'adresse : /recettes?categorie=dessertrecherche, filtre, pagination
$_POSTle corps de la requêtecréation, modification, mot de passe

La méthode GET met les données dans l'adresse, visible de tous. N'y envoie jamais d'information sensible. La méthode POST convient aux actions qui modifient quelque chose.

recettes.php
<?php
$categorie = $_GET["categorie"] ?? "toutes";
echo "Catégorie demandée : " . $categorie;

L'opérateur ?? donne une valeur de secours si le paramètre est absent.

Recevoir le formulaire

Le même fichier peut afficher le formulaire puis traiter l'envoi. On détecte un envoi en regardant la méthode de la requête.

ajouter.php
<?php
declare(strict_types=1);

if ($_SERVER["REQUEST_METHOD"] === "POST") {
    $titre = trim($_POST["titre"] ?? "");
    $duree = $_POST["duree"] ?? "";
    // validation à suivre
}

trim retire les espaces au début et à la fin. Toute donnée venue du navigateur est du texte, même un nombre.

Valider les données

Ne fais jamais confiance à ce qu'envoie l'utilisateur. Un visiteur peut vider un champ, saisir n'importe quoi, ou envoyer une requête sans passer par ton formulaire. La validation vérifie que chaque donnée a la forme attendue.

<?php
$erreurs = [];

if ($titre === "") {
    $erreurs[] = "Le titre est obligatoire.";
}

$dureeNombre = filter_var($duree, FILTER_VALIDATE_INT);
if ($dureeNombre === false || $dureeNombre <= 0) {
    $erreurs[] = "La durée doit être un entier positif.";
}

filter_var avec FILTER_VALIDATE_INT renvoie l'entier si la valeur en est un, sinon false. Le filtre FILTER_VALIDATE_EMAIL fait la même chose pour une adresse e-mail.

Si $erreurs est vide, tu peux utiliser les données. Sinon, tu réaffiches le formulaire avec les messages.

La faille XSS

Imagine qu'un visiteur saisisse ce titre :

<script>alert("piraté")</script>

Si tu l'affiches tel quel dans une page, le navigateur exécute ce script. C'est une faille XSS (Cross-Site Scripting) : du code injecté par un utilisateur s'exécute chez les autres visiteurs. Il pourrait voler leur session.

htmlspecialchars : le réflexe

htmlspecialchars remplace les caractères spéciaux du HTML (<, >, &, ", ') par des codes inoffensifs. Le navigateur affiche alors le texte au lieu de l'exécuter.

<?php
function e(string $texte): string
{
    return htmlspecialchars($texte, ENT_QUOTES, "UTF-8");
}
?>
<h2><?= e($titre) ?></h2>

Appelle-la sur toute donnée venue de l'extérieur au moment de l'afficher : formulaire, adresse, base de données. Écrire une petite fonction e() raccourcit le geste et évite les oublis.

Applique htmlspecialchars à l'affichage, pas à l'enregistrement. Les données restent ainsi intactes en base et protégées dans chaque page où tu les montres.

Après le traitement

Quand l'envoi a réussi, on redirige le visiteur vers une autre page. Sinon, recharger la page renverrait le formulaire une seconde fois.

<?php
if ($erreurs === []) {
    // enregistrer la recette (voir le chapitre suivant)
    header("Location: /recettes.php");
    exit;
}

header("Location: ...") demande au navigateur d'aller ailleurs. Le exit qui suit arrête le script : sans lui, PHP continue d'exécuter le code en dessous.

header doit être appelé avant tout affichage. Si du HTML est déjà parti, PHP ne peut plus modifier les en-têtes.

À retenir

  • $_GET lit les paramètres de l'adresse, $_POST le corps d'un formulaire.
  • Chaque name de champ devient une clé du tableau reçu ; toutes les valeurs sont du texte.
  • Ne fais jamais confiance aux données reçues : valide-les (trim, filter_var, tests de longueur).
  • Une faille XSS vient d'une donnée affichée sans protection.
  • Passe toute donnée extérieure dans htmlspecialchars au moment de l'afficher.
  • Après un traitement réussi, redirige avec header("Location: ...") puis exit.

Pour aller plus loin

Sources officielles

Ensuite

Projet
Lignes de code
Niveau
Sous-sol
Appartement
PHP
Pièce
5/7
Plan n°
php/05.formulaires
Lignes de code · fiches rédigées à partir des documentations officielles, sources citées en bas de chaque page.