Bonjour,
Je débute sous Symfony et j'ai un petit souci avec les routes dynamiques.
Malgré le fait que je me base bien sur la documentation (et malgré recherche sur le net évidement...), le framework ne parviens pas à traiter la route "app_lucky_word" que j'ai définie dans mon fichier "\config\routes.yaml" et me renvoi une 404 si j'appel le chemin, avec ou sans paramètre supplémentaire.
Contenu du fichier "\config\routes.yaml" :
#index:
# path: /
# controller: App\Controller\DefaultController::index
# the "app_lucky_number" route name is not important yet
app_lucky_number:
path: /lucky/number
controller: App\Controller\LuckyController::number
app_lucky_word:
path: /lucky/word/{tag}
controller: App\Controller\LuckyController::word
requirements:
tag: '[a-z]'
app_lucky_country:
path: /lucky/country
controller: App\Controller\LuckyController::country
Contenu du fichier "\src\Controller\LuckyController.php" :
<?php
// src/Controller/LuckyController.php
namespace App\Controller;
use Exception;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class LuckyController extends AbstractController {
private array $words = ['fr' => ['bonjour','bonsoir','au revoir'],
'en' => ['good morning', 'good evening', 'good bye']];
/**
* @Route("/lucky/number/", name="app_lucky_number")
*/
public function number(): Response
{
$number = random_int(0, 100);
return $this->render('lucky/number.html.twig', ['number' => $number]);
}
/**
* @Route("/lucky/word/{tag}", name="app_lucky_word")
*/
public function word(string $tag) : Response {
$lang_tag = $tag;
if(!in_array($lang_tag, $this->words)) {
throw new Exception($lang_tag.' is not a valid lang tag');
}
return $this->render('lucky/word.html.twig', ['word' => $this->words[$lang_tag][rand(0, 2)]]);
}
/**
* @Route("/lucky/country/", name="app_lucky_country")
*/
public function country(): Response
{
$countries = ['france','usa','italie'];
$country = $countries[random_int(0, 2)];
return $this->render('lucky/country.html.twig', ['country' => $country]);
}
}
Ce que je veux :
Je veux que Symfony parse la route et pointe vers la méthode "word" de la class "LuckyController".
Ce que j'obtiens :
Une belle erreur 404 avec le message "No route found for "GET http://synfony.local/lucky/word/" en en-tête.
L'exception est levée au niveau de la ligne 137 du fichier "\vendor\symfony\http-kernel\EventListener\RouterListener.php"
Par contre, c'est OK avec les routes statiques "app_lucky_country", "app_lucky_number".
Ce que j'ai déjà fait :
Franchement, je ne vois pas ce que je fais mal... ou, ce que je fais que je ne devrais pas faire... c'est surement un truc de base... mais là je vois pas...
Merci d'avance pour votre aide,
ok, alors essaye d'enlever le requirements temporairement, je ne suis pas sur que ton expression est écrite correctement. Et regarde si ça passe.
Si toujours pas essaye déplacer la route en première position dans ton ficher yaml.
Hello,
Premier constat, tu déclares tes routes à deux endroits ! Dans le controlleur via les annotations, et également dans le fichier yaml. Il ne faut pas faire les deux.
Choisit la manière dans laquelle tu es le plus allaise.
Pour ma part je préfère déclarer les routes via annotations dans les controlleurs, c'est un choix purement personel, il n'y a pas un meiilleur choix que l'autre.
Autre chose, dans la route app_lucky_word, sur l'annotation tu n'as pas mis le "requirment" pour le paramêtre alors que tu le mets dans le fichier yaml.
Mis à part ça à première vu tout semble correct.
Pour déboguer que te donnes :
php bin/console --env=dev debug:router
Rien à voir, mais juste queslques constatations. Dans cette même route, tu mets en paramêtre tag la lang, et tu déclares un tableau avec une phrase, je constate 4 choses ici
URL avec la locale en param : https://symfony.com/doc/current/translation/locale.html#the-locale-and-the-url
Paramêtre requis : https://symfony.com/doc/current/routing.html#parameters-validation
Translator : https://symfony.com/doc/current/translation.html
Hello Gulivert,
Désolé, je ne l'ai pas précisé mais j'avais déjà essayé de retirer les annotations au niveau de la méthode "word()".
Je viens de refaire un essai en retirant toutes notions d'annotation présentes dans mon controleur, les commentaires + le "use Symfony\Component\Routing\Annotation\Route"
J'ai malheureusement toujours le même problème...
La commande php bin/console --env=dev debug:router
affiche bien la liste des Routes.
Personnelement, je prefere regrouper mes routes dans un fichier "à part", c'est ce que je fait dans les autres framework que j'utilise, donc je vais garder mes habitudes.
Concernant la qualité du code, je suis en mode brouillon, c'est code de "remplissage" qui ne correspond pas à un fonctionnel définitif.
Je note tes remarques concernant le Translator et l'Exception (j'en suis au niveau 0.2 de mon apprentissage de Symfony...).
re
Bon c'est bon j'ai trouvé en refaisant un php bin/console router:match
sur ma Route app_lucky_word.
Le problème venait du paramétrage du "requirements" dans le fichier Yaml, apparement l'expression régulière ne convient pas... bref je l'ai retiré et ça fonctionne (je ferai le contrôle des paramètres moi-même à l'intérieur de la méthode...).
Au passage, il y a une autre coquille dans le code, au niveau de la ligne if(!in_array($lang_tag, $this->words)) {
, je fais un "in_array" au lieu d'un "array_key_exists" ^^
Encore merci pour tes infos et bon dimanche.
Pas de problème et bien joué :)
Pour l'expression je pense qu'elle devrait être :
requirements:
tag: '\[a-z\]'