Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Formations en ligne à Excel, Word, Office, Teams... Formez-vous en toute autonomie. Je les découvre !

Le routage

Organisation de l’application

Dans notre application, nous n’avons pour l’instant qu’un seul contrôleur, TestController, et, à l’intérieur de celui-ci, deux actions : index() et redirection(). Il est facile d’imaginer que, dans la pratique, vous aurez plusieurs contrôleurs et plusieurs actions disponibles. Chaque action correspondra à une requête de l’utilisateur.

Il faut commencer à se poser la question du découpage de l’application.

Combien vais-je avoir de contrôleurs ?

Combien d’actions aurais-je pour chaque contrôleur ?

Il n’y a pas de règles précises, mais sachez que plus votre application est découpée, mieux c’est.

Pour vous aider dans votre découpage, rappelez-vous qu’une action permet d’afficher une vue. Autrement dit, une action peut être définie pour l’affichage de chacune de vos pages affichées.

Un contrôleur va regrouper plusieurs actions. On peut définir un contrôleur pour chaque type de page, par exemple. Une pratique assez répandue (mais ce n’est pas la seule) est d’avoir un contrôleur pour la partie Front et un contrôleur qui gère le Back Office, c’est-à-dire l’administration de votre site. Un autre critère pour votre découpage est que vos actions...

Intérêt des routes

Les routes sont des indications pour permettre, en fonction d’une requête utilisateur (une URL), de retrouver le contrôleur et l’action à exécuter.

Les routes qui vont permettre d’exécuter les actions sont définies par défaut grâce aux annotations.

Reprenons notre TestController tel qu’il est écrit :

class TestController extends AbstractController 
{ 
 
#[Route('/test', name: 'app_test',methods: ['GET', 'HEAD'] )] 
    public function index(Request $request): Response 
    { 
 
        $response=new Response(); 
 
        $response->setContent('Hello World'); 
        $response->headers->setCookie(Cookie::create('nom', 'Yves')); 
        return $response; 
    } 
} 

L’annotation #Route indique que la requête /test (localhost:8000/test dans le navigateur) va exécuter l’action qui suit, c’est-à-dire index(Request $request)

Mais comment Symfony sait-il où se trouve le contrôleur à instancier ?

Tout ceci est défini...

Routes sans annotations

Il est possible de ne pas utiliser les attributes pour les routes. Nous pouvons définir les routes dans un fichier YAML extérieur à la racine de /config.

Ce fichier est déjà créé à cet effet : config/routes.yaml.

Nous allons par exemple, indiquer une nouvelle route (on l’appellera /testroute) pour l’action index() du contrôleur TestController.

Ajoutez dans le fichier config/routes.yaml les instructions suivantes (sans effacer les lignes déjà contenues dans ce fichier) :

index: 
   path: /testroute 
   controller: App\Controller\TestController::index 

Testez cette nouvelle route avec l’URL : https://localhost:8000/testroute

Vous devez retrouver la page de test affichée (avec Hello World).

Nous pouvons donc définir une suite de routes indépendantes dans le fichier config/routes.yaml.

Cependant, les attributes sont plus pratiques, car ils se trouvent en amont de chaque action et sont donc plus faciles à manipuler. Dans la suite de cet ouvrage, nous continuerons à utiliser les annotations pour les routes.

Verbes des routes

Vous le savez, une requête HTTP dispose d’une méthode de transmission des paramètres appelé verbe.

Par exemple, une requête directement exécutée sur un navigateur possède le verbe GET.

Une requête appelée via la soumission d’un formulaire possède généralement le verbe POST.

Il est possible de préciser cette méthode dans l’annotation de la route (par défaut, c’est la méthode GET qui est choisie) :

#[Route('/test', name: 'app_test',methods: ['GET', 'POST'] )] 

Ici, par exemple, nous autorisons la route /test à être exécutée soit avec la méthode GET, soit avec la méthode POST.

Le fait de préciser le verbe de la route permet un meilleur contrôle de la requête utilisée et peut éviter certaines failles de sécurité.

Par exemple, une action qui récupère des données via l’objet $request avec la méthode query (exemple : $request->query->get(’info’)) doit avoir une route définie avec la méthode GET obligatoirement.

Paramètres des routes

Il est possible de définir des paramètres dans une route (comme dans une fonction PHP). Ces paramètres seront automatiquement transmis à l’action dans l’ordre où ils sont donnés.

Prenons un exemple.

Créons une troisième action dans TestController.

Appelons-la hello().

Appliquons-lui une route qui s’appellera /hello :

    #[Route('/hello', name: 'hello')] 
    public function hello() 
    { 
        $response=new Response("Hello !");  
    } 

Si nous souhaitons transmettre le nom et le prénom en paramètres de la route, il faut les indiquer entre {}, comme ci-dessous :

    #[Route('/hello/{nom}/{prenom}', name: 'hello')] 
    public function hello(Request $request,$nom,$prenom) 
    { 
        return new Response("Hello $prenom $nom !");  
 
    }   

Les paramètres sont transmis dans l’ordre donné dans la route et sont récupérés dans la méthode hello ($nom et $prenom), en faisant abstraction de l’objet...

Paramètres conditionnels

Il est possible de définir des valeurs par défaut aux paramètres de l’action.

Exemple

    #[Route('/hello/{nom}/{prenom}', name: 'hello')] 
    public function hello(Request $request, $nom,$prenom='')  
    {  
 
        return new Response("Hello $prenom $nom !");  
    } 

Ici, $prenom=’’ signifie que si on ne précise pas la valeur de ce paramètre dans la route, il sera vide par défaut.

Ainsi, il n’est plus obligatoire de préciser le paramètre prénom dans la requête (John est omis) : https://localhost:8000/hello/Doe

Validation des paramètres

Il est toujours prudent de vérifier les valeurs transmises par le client dans la requête. Celui-ci peut en effet essayer de faire passer du code dans les paramètres (en JavaScript généralement) pour exécuter un traitement qui piratera vos données. C’est le principe d’une faille de sécurité appelée Cross-Site Scripting. 

Pour éviter cela, vous pouvez tester le type des paramètres transmis (comme dans n’importe quelle fonction PHP).

Prenons un exemple.

Ajoutons le paramètre age dans la route, mais en précisant le type du paramètre dans l’action hello() :

    #[Route('/hello/{age}/{nom}/{prenom}', name: 'hello')] 
    public function hello(Request $request, int $age, $nom, $prenom='') 
    { 
 
        return new Response("Hello $prenom $nom vous avez $age   ans!"); 
    } 

int $age précise que le paramètre $age doit être un entier.

Il est possible d’aller plus loin dans les tests des valeurs des paramètres en utilisant l’option requirements.

Cette option permet de définir pour chaque paramètre une expression...

Liste des routes

Il est possible d’avoir la liste des routes présentes dans toute votre application en exécutant sur le terminal : php bin/console debug:router