Tenemos dos controllers en la clase BlogController:
// src/AppBundle/Controller/BlogController.php
// ...
class BlogController extends Controller
{
/**
* @Route("/blog/{page}", defaults={"page" = 1})
*/
public function indexAction($page)
{
// ...
}
/**
* @Route("/blog/{slug}")
*/
public function showAction($slug)
{
// ...
}
}
Ambas routes tienen patrones que hacen coincidir URLs como /blog/*. El routing de Symfony siempre hará coincidir la primera route que encuentre. La route blog_show nunca coincidirá. Una URL como /blog/my-blog-post coincidirá con la primera route y devolverá un valor my-blog-post al parámetro {page}.
Para solucionar esto podemos añadir restricciones a las routes. Las routes en este ejemplo funcionarán perfectamente si el placeholder de /blog/{page} sólo coincidiera con integers. Restricciones con expresiones regulares pueden añadirse en cada parámetro:
// src/AppBundle/Controller/BlogController.php
// ...
/**
* @Route("/blog/{page}", defaults={"page": 1}, requirements={
* "page": "\d+"
* })
*/
public function indexAction($page)
{
// ...
}
El requisito \d+ es una expresión regular que indica que el valor del parámetro {page} debe ser un número. Ahora una route como my-blog-post sólo coincidirá con la segunda route /blog/{slug}.
El orden de las routes es muy importante. Si se cambiara el orden en que están definidas las routes anteriores, la URL /blog/2 coincidiría con /blog/{slug} y nunca llegaría a /blog/{page}. Con un orden aduecuado y el uso de restricciones se puede conseguir lo que se quiera.
Ya que los requisitos están descritos con expresiones regulares, la complejidad y flexibilidad de cada requisitio depende de ti. Suponemos que la homepage de una aplicación está disponible en dos idiomas diferentes, basándose en la URL:
// src/AppBundle/Controller/MainController.php
// ...
class MainController extends Controller
{
/**
* @Route("/{_locale}", defaults={"_locale": "en"}, requirements={
* "_locale": "en|fr"
* })
*/
public function homepageAction($_locale)
{
}
}
La aplicación responderá con esta route si se trata de en o fr. Si se intenta con es no responderá esta route.