Le carnet d'adresses
Dans le carnet du téléphone, on ajoute un contact (Create), on le consulte (Read), on corrige son numéro (Update), on le supprime (Delete). Chaque écran d'administration répète ces quatre gestes sur une table.
Les quatre opérations d'une page d'administration (Create, Read, Update, Delete) avec PDO, un formulaire qui sert à la fois à créer et à modifier, la validation côté serveur, le modèle « POST puis redirection » et les erreurs de contraintes.
L'équipe de Souk Atlas veut gérer ses catégories sans ouvrir phpMyAdmin : une liste, un bouton Ajouter, un lien Modifier sur chaque ligne, un bouton Supprimer. Ces quatre gestes forment le CRUD, le cœur de presque toutes les applications de gestion.
index.php (Read) : SELECT des catégories, avec un lien Modifier et un bouton Supprimer sur chaque ligne.
Une organisation simple, une page par opération :
| Fichier | Méthode | Rôle |
|---|---|---|
index.php | GET | liste des lignes, avec liens et boutons |
ajouter.php | POST | INSERT, puis retour à la liste |
modifier.php?id=4 | GET puis POST | formulaire pré-rempli, puis UPDATE |
supprimer.php | POST | DELETE, puis retour à la liste |
Les opérations qui modifient la base passent toujours par POST. Un GET (un lien, une adresse tapée) ne doit que lire.
La page de modification fait deux choses selon la méthode :
modifier.php?id=4), elle lit la ligne et pré-remplit le formulaire avec value="<?= htmlspecialchars(...) ?>" ;UPDATE avec l’identifiant reçu dans un champ caché, puis redirige.$req = $pdo->prepare('UPDATE categories SET nom = :nom WHERE id = :id');
$req->execute(['nom' => $nom, 'id' => $id]);
echo $req->rowCount() . ' ligne modifiée';
Avec MySQL, rowCount() vaut 0 si la ligne existe mais que la nouvelle valeur est identique à l’ancienne : MySQL ne compte que les lignes réellement changées.
Une catégorie utilisée par des produits ne peut pas être supprimée : la clé étrangère produits.categorie_id la protège (module 06). MySQL répond par une erreur, et PDO lance une exception qu’on attrape pour afficher un message clair.
Dans le carnet du téléphone, on ajoute un contact (Create), on le consulte (Read), on corrige son numéro (Update), on le supprime (Delete). Chaque écran d'administration répète ces quatre gestes sur une table.
Une fois le paiement validé, la caissière vous tend le ticket et passe au client suivant. Si vous rafraîchissez la page juste après un envoi, le navigateur ne doit pas « repayer » : d'où la redirection après chaque POST.
La page s'affichera ici.
Le navigateur demandera /index.php au serveur, qui exécutera le PHP et renverra du HTML.
Consignes 0 / 3
Fusionnez ajouter.php et modifier.php en un fichier form.php : sans id, il crée ; avec ?id=, il pré-remplit et met à jour.
<?php require __DIR__ . '/db.php'; $id = (int) ($_POST['id'] ?? $_GET['id'] ?? 0); $nom = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') { $nom = trim($_POST['nom'] ?? ''); if ($nom !== '') { if ($id) { $pdo->prepare('UPDATE categories SET nom = ? WHERE id = ?')->execute([$nom, $id]); } else { $pdo->prepare('INSERT INTO categories (nom) VALUES (?)')->execute([$nom]); } header('Location: index.php'); exit; } } elseif ($id) { $req = $pdo->prepare('SELECT nom FROM categories WHERE id = ?'); $req->execute([$id]); $nom = $req->fetchColumn(); } ?> <h1><?= $id ? 'Modifier' : 'Ajouter' ?> une catégorie</h1> <form method="post"> <input type="hidden" name="id" value="<?= $id ?>"> <input name="nom" value="<?= htmlspecialchars($nom) ?>"> <button>Enregistrer</button> </form>
Sur la fiche d'un produit, un petit formulaire « Réceptionner » ajoute une quantité au stock (UPDATE ... SET stock = stock + ?). Refusez une quantité négative ou nulle.
<?php require __DIR__ . '/db.php'; $id = (int) ($_POST['id'] ?? 0); $qte = (int) ($_POST['qte'] ?? 0); if ($qte <= 0) { exit('La quantité doit être positive.'); } $req = $pdo->prepare('UPDATE produits SET stock = stock + :qte WHERE id = :id'); $req->execute(['qte' => $qte, 'id' => $id]); if ($req->rowCount() === 0) { exit('Produit introuvable.'); } header("Location: produit.php?id=$id"); exit;
Un collègue propose un simple lien <a href="supprimer.php?id=4">Supprimer</a>. Expliquez en trois points pourquoi c'est une mauvaise idée.
1. Un GET doit seulement lire : les navigateurs, les robots d'indexation et certains antivirus suivent les liens tout seuls, et pourraient tout supprimer. 2. Un lien peut être déclenché depuis un autre site (une image <img src="...supprimer.php?id=4">) sans que l'administrateur s'en rende compte (attaque CSRF, leçon C.5). 3. Un POST passe par un formulaire, qu'on peut protéger par un jeton et faire précéder d'une confirmation.