Des contrôleurs en classes

Exercice 7 sur 7 du chapitre 6 · 200 XP · 3 objectifs vérifiés par des tests

Notions abordées : ContrôleurCallable::classInstanciation dynamique

public/index.php déborde : cinq routes, cinq fonctions anonymes, et bientôt d'autres. Madame Lou demande un dernier rangement avant la mise en ligne : un contrôleur par page, une classe dans src/Controleur/. Le contrôleur frontal ne fera plus qu'associer les adresses aux contrôleurs.

Votre mission

  1. Créez dans src/Controleur/ les classes UneControleur, ArticleControleur, RubriqueControleur, RechercheControleur et AnnonceControleur, dans l'espace de noms Gazette\Controleur. Créez chaque fichier avec le bouton « Créer un fichier » de l'éditeur : un fichier par classe, qui porte son nom (src/Controleur/UneControleur.php).
  2. Déplacez-y le code des fonctions anonymes : afficher() pour les quatre premières (avec array $parametres pour l'article et la rubrique), proposer() pour l'annonce. N'oubliez pas les use.
  3. Dans public/index.php, chaque route désigne son contrôleur par un tableau : [UneControleur::class, 'afficher'].
  4. Quand une route est trouvée, créez le contrôleur et appelez sa méthode avec les paramètres de l'adresse, toujours dans le try qui attrape ArticleIntrouvable.

Ce que Symfony ferait pour vous

Vous venez d'écrire, en petit, ce que fait un framework : un contrôleur frontal (public/index.php), un routeur, des contrôleurs, des gabarits, des réponses avec leur code HTTP, des exceptions, des formulaires validés et échappés. Symfony ajoute les routes en attributs (#[Route('/articles/{slug}')]), Twig qui échappe tout seul, un composant de formulaires, et la base de données. Vous savez maintenant ce qu'il y a sous le capot.

Rappel

[UneControleur::class, 'afficher'] désigne une méthode sans l'appeler : la classe et le nom de la méthode. new $classe() crée un objet de la classe dont le nom est dans $classe, et $objet->$methode() appelle la méthode dont le nom est dans $methode.

Pour récupérer les deux morceaux d'un coup, [$classe, $methode] = $route[1]; range le premier élément du tableau dans $classe et le second dans $methode.

UneControleur::afficher() et RechercheControleur::afficher() n'ont pas besoin des paramètres de l'adresse. Vous pouvez quand même les appeler avec $route[2] : PHP ignore sans broncher les arguments en trop passés à une méthode écrite en PHP, ce qui permet d'appeler tous les contrôleurs de la même façon.