Le routeur de Symfony
Qu'est-ce qu'un routeur ?
Le routeur est l’un des composants les plus importants de Symfony.
C'est lui qui fait le lien entre une URL demandée par l’utilisateur et le contrôleur chargé de répondre à cette requête.
Dan notre schéma, nous avons un routeur et chaque route est réprésentée par une flèche. Ces routes peuvent être associés à des chemins qui permettent d'envoyer la bonne page à l'utilisateur.
Dans Symfony, cette correspondance s'appelle le mapping des routes.
Le routeur en action !
Donc, Symfony envoie la requête au Routeur. Ensuite, le routeur compare l'URL à toute les routes. Lorsqu'il trouve une correspondance, il appelle la méthode du contrôleur associée et le contrôleur renvoie la réponse.
Comment déclarer une route ?
Déclarer une route via une annotation (attribut PHP)
Nous pouvons déclarer une route grâce aux attributs placés au-dessus des méthodes du contrôleur.
Revoyons notre code dans notre contrôleur.
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HelloController extends AbstractController
{
#[Route('/hello', name: 'app_hello')]
public function index(): Response
{
return $this->render('hello/index.html.twig', [
'controller_name' => 'HelloController',
]);
}
}
La déclaration de la route se trouve dans la ligne 11 :
#[Route('/hello', name: 'app_hello')]
Et '/hello' est l'URL que l'utilisateur doit utiliser pour que la méthode du contrôleur puisse renvoyer la réponse correspondante.
Ne tenez pas compte pour l'instant de name: 'app_hello'. Nous en reparlerons plus tard.
Créer une nouvelle route
Pour créer une nouvelle route il faut créer une nouvelle méthode dans notre contrôleur.
Ajouter un nouveau contrôleur simple :
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HelloController extends AbstractController
{
#[Route('/hello', name: 'app_hello')]
public function index(): Response
{
return $this->render('hello/index.html.twig', [
'controller_name' => 'HelloController',
]);
}
#[Route('/articles', name: 'app_articles')]
public function list(): Response
{
return new Response('Liste des articles');
}
}
Nous avons ajouté une nouvelle méthode (lignes 20 à 24) contenant une nouvelle route et une réponse plus simple que la précédente. En effet, au lieu de renvoyer le contenu d’un fichier Twig, elle retourne simplement une chaîne de caractères : “Liste des articles”.
Dans votre navigateur, tapez maintenant l'URL suivante :
http://localhost:8000/articles
Normalement, ce contenu devrait s’afficher dans votre navigateur :
Parfait, nous avons créé une nouvelle route grâce à l'attribut que nous avons ajouté au-dessus de la méthode. 👍
Ajouter des paramètres dynamiques
Vous pouvez aussi définir des routes dynamiques, avec des variables dans l’URL.
Le mieux pour comprendre, c'est de créer un nouvelle méthode.
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
final class HelloController extends AbstractController
{
#[Route('/hello', name: 'app_hello')]
public function index(): Response
{
return $this->render('hello/index.html.twig', [
'controller_name' => 'HelloController',
]);
}
#[Route('/articles', name: 'app_articles')]
public function list(): Response
{
return new Response('Liste des articles');
}
#[Route('/article/{id}', name: 'app_article_show')]
public function show(int $id): Response
{
return new Response('Affichage de l\'article avec l\'ID : ' . $id);
}
}
Par rapport à notre dernière méthode créée, on ajoute d'autres choses que nous ne connaissons pas pour l'instant.
-
{id}(ligne 26 -
(int $id)(ligne 29)
Si l’utilisateur visite /article/5, Symfony exécute la méthode show() avec $id = 5.
Par conséquent, il existe un lien entre {id} et (int $id). Pour que cette relation fonctionne, il est impératif qu’ils portent le même nom.
Ensuite, le contrôleur envoie la réponse avec la contenu de la variable $id.
Faisons un test dans notre navigateur :
http://localhost:8000/article/5
Voici le contenu qui s'affiche :
Si on remplace 5 par 6, la page va d'adapter :
Liste des routes disponibles
Pour afficher la liste complète des routes de votre projet, tapez la commandes suivante :
php bin/console debug:router
Vous verrez vos routes, ainsi que d’autres routes générées automatiquement par Symfony. C’est tout à fait normal.
profiler_search ANY ANY ANY /_profiler/search
_profiler_search_bar ANY ANY ANY /_profiler/search_bar
_profiler_phpinfo ANY ANY ANY /_profiler/phpinfo
_profiler_xdebug ANY ANY ANY /_profiler/xdebug
_profiler_font ANY ANY ANY /_profiler/font/{fontName}.woff2
_profiler_search_results ANY ANY ANY /_profiler/{token}/search/results
_profiler_open_file ANY ANY ANY /_profiler/open
_profiler ANY ANY ANY /_profiler/{token}
_profiler_router ANY ANY ANY /_profiler/{token}/router
_profiler_exception ANY ANY ANY /_profiler/{token}/exception
_profiler_exception_css ANY ANY ANY /_profiler/{token}/exception.css
app_hello ANY ANY ANY /hello
app_articles ANY ANY ANY /articles
app_article_show ANY ANY ANY /article/{id}
Utiliser les routes dans Twig !
Il est possible d’utiliser des routes dans Twig. Bien sûr, on peut insérer des liens classiques, puisque Twig fonctionne comme une page HTML. Cependant, il est souvent préférable d’utiliser le routeur intégré de Twig, qui offre une solution plus propre et flexible.
Nous allons ouvrir le fichier Twig qui se trouve dans templates/hello/index.html.twig. Je vais y ajouter un lien en utilisant le routeur.
{% extends 'base.html.twig' %}
{% block title %}Hello HelloController!{% endblock %}
{% block body %}
<style>
.example-wrapper { margin: 1em auto; max-width: 800px; width: 95%; font: 18px/1.5 sans-serif; }
.example-wrapper code { background: #F5F5F5; padding: 2px 6px; }
</style>
<div class="example-wrapper">
<h1>Hello {{ controller_name }}! ✅</h1>
This friendly message is coming from:
<ul>
<li>Your controller at <code>/Users/henrique/Documents/apps/lab/mon_projet/src/Controller/HelloController.php</code></li>
<li>Your template at <code>/Users/henrique/Documents/apps/lab/mon_projet/templates/hello/index.html.twig</code></li>
</ul>
<p><a href="{{ path('app_article_show', {'id': 10}) }}">Lire l’article 10</a></p>
</div>
{% endblock %}
Le code {{ path('app_article_show', {'id': 10}) }} va générer le code suivant à la sortie lorsque que la réponse est retournée :
<a href="/article/10">Lire l’article 10</a>
Par conséquent, lorsque l’on clique sur le lien, celui-ci redirige vers la page correspondante.
C'est important de bien comprendre la signification de path('app_article_show'.
path (ou url)
path est une fonction Twig qui génère automatiquement l’URL correspondant à une route définie dans votre application Symfony (il est possible également d'utiliser url à la place).
app_article_show
app_article_show est le nom de la route que vous avez déclarée dans votre contrôleur grâce à l’attribut #[Route] ; il permet à Symfony de savoir quelle URL construire pour cette page.
#[Route('/article/{id}', name: 'app_article_show')]
public function show(int $id): Response
{
return new Response('Affichage de l\'article avec l\'ID : ' . $id);
}
Maintenant, nous comprenons le rôle de name: 'app_article_show' dans l'attribut de la méthode.
{'id': 10}
{'id': 10} est facultatif et permet de passer un paramètre dynamique à la route lorsque c'est nécessaire.
Dans la prochaine leçon, nous allons approfondir l’utilisation de Twig.
