13 - Symfony : Le param converter
Objectifs
- ✅ Comprendre le principe du param converter
- ✅ Connaître des cas d'utilisation plus avancés
Pré-requis
Avoir terminé la quête
Introduction
User stories 📋
en tant que visiteur, je souhaite récupérer les données d'une série
en tant que visiteur, je souhaite récupérer la liste des séries
en tant que contributeur, je souhaite ajouter une série
In progress 🤸
en tant que visiteur, je souhaite afficher les séries par catégories
Doing 🏗️
mise en place du param converter
Done ✅
mise en place de la relation bidirectionnelle
en tant que visiteur, je souhaite visualiser la fiche d'une série
création de la méthode show dans le contrôleur CategoryController
Le param converter est une fonctionnalité très pratique de Symfony, qui te permet de convertir directement des paramètres passés à travers une route en objets.
Sommaire
Le principe du param converter
Soit une méthode show() avec un attribut de route, permettant de récupérer une série, par exemple :
#[Route('/program/{id}/', name: 'program_show')]
public function show(int $id, ProgramRepository $programRepository): Response
{
$program = $programRepository->find($id);
return $this->render('program/show.html.twig', ['program' => $program]);
}
- Tu récupères un identifiant unique de Program, l'
id, - Tu passes ce paramètre issu de ta route en paramètre à ta méthode du controller.
- La variable
$idest utilisée pour récupérer le Program avec l'idcorrespondant, via la méthodefind()deProgramRepository.
Pour rappel : la méthode find() est l'équivalent de findOneById().
Tu es donc passé d'un paramètre de route à un objet $program. C'est là que le param converter peut te faire gagner du temps et des lignes de code ! C'est très simple à utiliser, car ce mécanisme est activé par défaut dans Symfony.
👀 Regarde le code ci-dessous :
#[Route('/program/{id}/', name: 'program_show')]
public function show(Program $program): Response
{
return $this->render('program.html.twig', ['program'=>$program]);
}

Et voilà ! Tu obtiens directement l'objet Program qui correspond à l'id saisi dans ta route. Que s'est-il passé ?
Tu vois que le paramètre de la méthode est directement $program. Ce qui est important ici, ce n'est pas son nom, mais son type : Program.
Tu as typé le paramètre pour lui dire que tu voulais un objet Program, mais tu as entré un integer correspondant à l'id.
Il y a donc eu une conversion automatique de ton paramètre ! Le param converter n'est donc rien de plus !
Si tu indiques que tu souhaites un objet de type Program, il va automatiquement effectuer la requête find() du premier exemple.
Attention, cependant ! Pour que cela fonctionne, il faut que ton paramètre (ici {id}) corresponde à une propriété de ton entité et qu'il s'agisse d'un champ unique (c’est le cas ici, puisque le champ id est une primary key) !
Il s'agit bien du nom de la propriété de l'entité et non pas du nom du champ en base de données (bien que parfois identique).
Note : lorsque tu as besoin de faire appel à ta route depuis Twig, par exemple, il faut bien que tu utilises le paramètre "id", tel qu'il est défini dans l'attribut #[Route()], et non appeler ton paramètre "program".
<a href="{{ path('program_show', {'id': 1 }) }}">...</a>
Concentre-toi sur le début. Note également que l'attribut #[ParamConverter] peut être omis pour les cas les plus simples, comme ceux évoqués ci-dessus.
... qui démontre l'utilisation du param converter.
Utilisation avancée
Dans certains cas, depuis une route, tu as besoin de récupérer des informations de plusieurs entités, mais tu ne peux pas avoir deux fois le même paramètre.
Imaginons que l'on souhaite afficher la critique d'une série par exemple.
Dans ce cas, la route #[Route("/program/{id}/comment/{id}")] ne serait pas valide.
Comment faire alors pour éviter les ambiguïtés ? Car le param converter doit distinguer le paramètre correspondant à la propriété id de l'entité Program, de celle correspondant à l’id de la présupposée entité Comment.
Il faut alors tout simplement utiliser des noms de paramètres différents, par exemple :
Solution 1 : Utiliser un nom de paramètre identique au nom de l'entité
#[Route("/program/{program}/comment/{comment}", name:"program_show_comment")]
public function showProgramComment(Program $program, Comment $comment): Response
{
return $this->render('comment.html.twig', [
'program' => $program,
'comment' => $comment,
]);
}
Lorsque le param converter rencontre un paramètre portant le même nom que l'entité, il cherchera alors à utiliser l'id pour faire la conversion. Cela permet alors de lever l'ambiguïté.
Au niveau de l'appel de la route (dans Twig par exemple), il faudra alors bien spécifier les paramètres 'program' et 'comment' et non pas 'id'.
Ex: <a href="{{ path("program_show_comment", {"program": 1, "comment": 2 })}}">...</a>
Solution 2 : Mapper manuellement le paramètre à la propriété de l'entité
#[Route("/program/{program_id}/comment/{comment_id}", name:"program_show_comment")]
public function showProgramComment(Program $program, Comment $comment): Response
{
return $this->render('comment.html.twig', [
'program' => $program,
'comment' => $comment,
]);
}
❌ ne fonctionne pas
Ici les paramètres ont un nom différent de l'entité. Ça ne peut pas fonctionner, puisque l'entité Program ne contient pas de propriété $program_id et Comment de propriété $comment_id. Il faut alors ajouter un attribut devant les paramètres cette fois (oui c'est possible 😎) #[MapEntity()] qui va permettre d'indiquer correctement le lien entre paramètres et propriétés d'entité. Attention à bien ajouter le use Symfony\Bridge\Doctrine\Attribute\MapEntity; en début de fichier.
On obtient alors :
#[Route('/program/{program_id}/comment/{comment_id}', name: 'program_show_comment')]
public function showProgramComment(
#[MapEntity(mapping: ['program_id' => 'id'])] Program $program,
#[MapEntity(mapping: ['comment_id' => 'id'])] Comment $comment
): Response {
return $this->render('comment.html.twig', [
'program' => $program,
'comment' => $comment,
]);
}
✅ correct
👀 Dans l'exemple ci-dessus, on indique que le paramètre program_id doit être considéré comme correspondant à la propriété $id de l'entité Program et que le paramètre comment_id doit être considéré comme correspondant à la propriété $id de l'entité Comment.
Au niveau de l'appel de la route (dans Twig par exemple), il faudra alors bien spécifier les paramètres 'program_id' et 'comment_id' et non pas 'id'.
Ex: <a href="{{ path("program_show_comment", {"program_id": 1, "comment_id": 2 })}}">...</a>
Il existe de nombreuses autres options que tu peux découvrir dans la documentation pour faire des choses encore plus complexes, mais cela dépasse le cadre de cette quête.
Date converter
Le terme de param converter est souvent utilisé pour les Doctrine converters, c'est-à-dire transformer un paramètre de route en entité Doctrine. Cependant, ils peuvent servir à d'autres conversions paramètre > objet. Un exemple concret est le Date Converter qui transforme un paramètre au format "date" automatiquement en un objet Datetime.
#[Route('/wild/historic/{start}')]
public function historic (\DateTime $start): Response
{
// si {start} est au format 'YYYY-mm-dd', $start est converti en un objet \DateTime
// par exemple : /wild/historic/2025-09-18
}
Ici, si {start} est au format date par défaut (YYYY-mm-dd, mais des options supplémentaires permettent d'ajuster ce comportement), alors le Date Converter fait son travail et la chaîne de caractères est convertie automatiquement en objet \Datetime, car le paramètre $start de la fonction historic() est typé en ce sens.
Remarque : il est également possible de développer ses propres custom converters pour des usages plus avancés.
plus d'infos sur les autres types de converters.
en fonction des cas.
listant toutes les options plus ou moins complexes des param converters.
💪 Challenge
Utilise un param converter
Pour ton projet Wild Séries, reprends ta classe ProgramController.
- Modifie la méthode
show()(route = "program_show") pour récupérer l'objetProgramdirectement depuis les paramètres de la méthode grâce au param converter (modifie le typage de ton paramètre). - Modifie la méthode
showSeason()(route = "program_season_show") pour récupérer les objetsProgrametSeasondirectement depuis les paramètres de la méthode grâce au param converter (modifie le typage de tes paramètres). - Crée une méthode
showEpisode(Program $program, Season $season, Episode $episode)- La route de cette méthode sera donc de la forme
/program/{programId}/season/{seasonId}/episode/{episodeId}et le nom de la route seraprogram_episode_show - Récupère les objets
Program,SeasonetEpisodedirectement depuis les paramètres de la méthode grâce au param converter - Cette méthode retournera une nouvelle vue : templates/program/episode_show.html.twig.
Cette vue affichera :
- le nom de la série
- le numéro de la saison
- le numéro et le titre de l'épisode
- le résumé de l'épisode
- La route de cette méthode sera donc de la forme
- Sur la page de détail d'une saison, ajoute un lien sur chaque épisode afin de pouvoir accéder à sa fiche.
Critères de validation
- Dans
ProgramController, la méthodeshow()permet de récupérer l'objetprogramvia le param converter, à partir de l’id en paramètre de la route - Dans
ProgramController, la méthodeshowSeason()permet de récupérer les objetsprogrametseasonvia le param converter, à partir de l’id en paramètre de la route - Dans
ProgramController, la méthodeshowEpisode()permet de récupérer les objetsprogram,seasonetepisodevia le param converter, à partir de l’id en paramètre de la route - La méthode
showEpisode()rend une vue affichant le nom de la série, la saison, ainsi que les informations de l'épisode. - Le code est disponible sur un repository GitHub, avec une branche correspondant à cette quête.