简体   繁体   中英

Symfony2 Controller Route clash

Hey all I have a bit of a problem with root annotations in Symfony2.

I have two different controllers that call methods from the same URL positions /test.

Controller 1:

    **
     * @Route("/test", service="myProject.test.controller.art")
     * @Cache(expires="+5 minutes", public=true)
     */
    class BlogController
    {

      /**
         * @Route("/{text}", defaults={"text" = null})
         * @Route("/topic/{tag}", defaults={"tag" = null})
         * @Method({"GET"})

         */
        public function listAction(ArtQuery $query)
        {
           //.................
        }
    }

Controller 2:

**
 * @Route("/test" , service="myProject.test.controller.sitemap"))
 * @Cache(expires="+5 minutes", public=true)
 */
class SitemapController
{
/**
     * @Route("/sitemap.xml/")
     * @Method({"GET"})
     */
    public function sitemapAction()
    {
       //..................
    }
}

The problem is that the second Controller is never matched only if is add in my @route("/sitemap.xml/") but I realy want the route to be only @route("/sitemap.xml") .

I think the problem is when i input the url /test/sitemap.xml Symfony treats sitemap.xml as /{text} variable route in first controller.

Can I make a exception so that first controller ends as soon as it hits sitemap.xml....?

I read something about requirements but dont quiet understand this concept

according to documentation

Earlier Routes always Win

What this all means is that the order of the routes is very important. If the blog_show route were placed above the blog route, the URL /blog/2 would match blog_show instead of blog since the {slug} parameter of blog_show has no requirements. By using proper ordering and clever requirements, you can accomplish just about anything.

http://symfony.com/doc/current/book/routing.html

i suggest to use yml or xml file for routing or you can make a requirement in your first route

   /**
     * @Route("/{text}", defaults={"text" = null}, requirements={"text" = "^(?!sitemap\.xml)$"})
     * @Route("/topic/{tag}", defaults={"tag" = null})
     * @Method({"GET"})

     */
    public function listAction(ArtQuery $query)
    {
       //.................
    }

The router will use the first route that matches the path.

The only way to prioritize a route over another which could match is to ensure that the stricter requirements are check before the weaker ones.

Normally this would be accomplished by placing the sitemapAction method above listAction . However since you have a controller for each of these, you will have to put the controllers in the correct order.

To do this you will need to add the controllers to the config individually like this:

app_sitemap:
    resource: "@AppBundle/Controller/SitemapController.php"
    type:     annotation
    prefix:   /


app_blog:
    resource: "@AppBundle/Controller/BlogController.php"
    type:     annotation
    prefix:   /

This way the controllers will be iterated in this order.

However it is better if you can give each route a unique path, perhaps:

@Route("/query/{text}", defaults={"text" = null})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM