Documentation · Chapitre 04

Atelier : terminer
le gestionnaire.

Rassemblez les notions dans une application utilisable, puis vérifiez chaque scénario comme un utilisateur et comme un développeur.

Nous poursuivons le projet reading-list. Les données seront conservées dans la session avant d’introduire une base de données.

CAHIER DES CHARGES

La page /books doit devenir un vrai point de départ.

  1. Afficher tous les livres de la session.
  2. Proposer un lien Ajouter un livre.
  3. Proposer Modifier et Supprimer pour chaque livre.
  4. Conserver les valeurs invalides et afficher les erreurs.
  5. Rediriger après chaque changement réussi.

Action index()

phpaml — zsh
public function index(Request $request): Response
{
    return $this->view('books/index.php', [
        'books' => $this->session->get('books', []),
    ]);
}

Vue de la liste

src/views/books/index.php

phpaml — zsh
<h1>Mes livres</h1>
<p><a href="/books/create">Ajouter un livre</a></p>

<?php if ($books === []): ?>
    <p>Aucun livre pour le moment.</p>
<?php else: ?>
    <ul>
    <?php foreach ($books as $book): ?>
        <li>
            <strong><?= $view->escape($book['title']) ?></strong>
            — <?= $view->escape($book['author']) ?>
            <a href="/books/<?= (int) $book['id'] ?>/edit">Modifier</a>
            <form method="post" action="/books/<?= (int) $book['id'] ?>/delete">
                <?= $view->csrfField() ?>
                <button type="submit">Supprimer</button>
            </form>
        </li>
    <?php endforeach; ?>
    </ul>
<?php endif; ?>

Action de suppression

phpaml — zsh
public function destroy(Request $request): Response
{
    $id = (int) $request->attribute('id');
    $books = $this->session->get('books', []);
    $books = array_values(array_filter(
        $books,
        static fn (array $book): bool => $book['id'] !== $id,
    ));
    $this->session->set('books', $books);

    return Response::redirect('/books', 303);
}

array_filter conserve les livres dont l’identifiant est différent. array_values remet les positions du tableau dans un ordre simple. L’identifiant métier du livre, lui, ne change pas.

Plan de vérification

Créer un livre valide303 → GET /books
Envoyer un titre vide422 + error
Retirer le jeton CSRF419
Modifier un identifiant absent404
Supprimer un livredisparaît de la liste
phpaml — zsh
aml routes
aml test

Ce que vous avez réellement appris

Vous n’avez pas seulement créé un formulaire. Vous avez séparé consultation et modification, lu une requête, validé ses valeurs, protégé une action, conservé un état entre plusieurs requêtes, choisi des statuts HTTP utiles et empêché la répétition d’un POST.

EN RÉSUMÉ

Ce qu’il faut retenir

  • Le navigateur aide, mais le serveur valide toujours.
  • csrfField() protège chaque formulaire de modification.
  • La vue échappe toute valeur dynamique.
  • Une redirection 303 termine proprement un POST.
  • La session convient à l’apprentissage, pas à la persistance définitive.