Symfony2控制器路由冲突

时间:2015-01-08 15:03:24

标签: php xml symfony

嘿,我对Symfony2中的根注释有点问题。

我有两个不同的控制器,它们从相同的URL位置/测试中调用方法。

控制器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)
        {
           //.................
        }
    }

控制器2:

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

问题是第二个Controller永远不会匹配我的@route("/sitemap.xml/")中的添加,但我真的希望路由只是@route("/sitemap.xml")

我认为问题是当我输入url /test/sitemap.xml时,Symfony将sitemap.xml视为第一个控制器中的/ {text}变量路由。

我是否可以设置一个例外,以便第一个控制器一旦到达sitemap.xml就结束....?

我读了一些关于要求的内容,但是没有理解这个概念

2 个答案:

答案 0 :(得分:1)

根据文件

  

早期路线总是胜利

     

这一切意味着路线的顺序非常重要。   如果blog_show路由位于博客路线上方,则为URL   自从{slug}以来,/ blog / 2将匹配blog_show而不是博客   blog_show的参数没有要求。通过使用正确的订购   和聪明的要求,你几乎可以完成任何事情。

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

我建议使用yml或xml文件进行路由 或者您可以在第一条路线中提出要求

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

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

答案 1 :(得分:1)

路由器将使用与路径匹配的第一条路由。

将路线优先于另一条路线的唯一方法是确保在较弱的路线之前检查更严格的要求。

通常,这可以通过将sitemapAction方法置于listAction之上来实现。 但是,由于每个控制器都有一个控制器,因此您必须按正确的顺序放置控制器。

要执行此操作,您需要将控制器单独添加到配置中,如下所示:

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


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

这样控制器将按此顺序迭代。

但是,如果你能给每条路线一个独特的路径,那就更好了:

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