路由
编辑本页警告:您正在浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 3.3,现已不再维护。
读本页的更新版本用于Sy欧宝娱乐app下载地址mfony 6.2(当前稳定版本)。
路由
对于任何严肃的web应用程序来说,漂亮的url都是绝对必须的。这意味着留下丑陋的urlindex . php ?article_id = 57
比如/读/ intro-to-sy欧宝娱乐app下载地址mfony
.
拥有灵活性更为重要。如果您需要更改页面的URL/博客
来/欧宝app在哪里找新闻
?您需要查找和更新多少链接才能做出更改?如果您正在使用Symfony的路欧宝娱乐app下载地址由器,更改很简单。
Symf欧宝娱乐app下载地址ony路由器允许您定义可映射到应用程序不同区域的创造性url。在本文结束时,您将能够:
- 创建映射到控制器的复杂路由
- 在模板和控制器中生成url
- 从包(或其他任何地方)加载路由资源
- 调试路由
路由的例子
一个路线是从URL路径到控制器的映射。例如,假设您想匹配任何URL/博客/我的帖子
或/博客/ all-about-s欧宝娱乐app下载地址ymfony
然后把它发送给一个控制器,这个控制器可以查找并渲染那个博客条目。路线很简单:
- 注释
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/ / src / AppBundle /控制器/ BlogController.php名称空间AppBundle\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\控制器;使用Sensio赞助\包\FrameworkExtraBundle\配置\路线;类BlogController扩展控制器{/** *匹配/blog **@Route("/blog", name="blog_list") */公共函数listAction(){/ /……}/** *匹配/博客/** *@Route("/blog/{slug}", name="blog_show") */公共函数showAction($鼻涕虫){// $slug将等于URL的动态部分//例如:at /blog/ ay-routing,那么$slug=' ay-routing'/ /……}}
多亏了这两条路线:
- 如果用户转到
/博客
,则匹配第一个路由listAction ()
执行; - 如果用户转到
/博客/ *
,则第二条路由匹配和showAction ()
是执行。因为路由路径是/博客/{蛞蝓}
,一个美元蛞蝓
变量传递给showAction ()
匹配这个值。例如,如果用户转到/博客/ yay-routing
,然后美元蛞蝓
就等于yay-routing
.
每当你有{占位符}
在路由路径中,该部分成为通配符:它匹配任何价值。你的控制器现在可以也有一个论证叫做美元的占位符
(通配符和参数名必须匹配)。
每条路由也有一个内部名称:blog_list
而且blog_show
.它们可以是任何东西(只要每个都是唯一的),还没有任何意义。稍后,您将使用它来生成url。
这就是Symfony路由器的目标:将请求的URL欧宝娱乐app下载地址映射到控制器。在此过程中,您将学习各种技巧,使映射即使是最复杂的url也很容易。
添加{通配符}需求
想象一下blog_list
route将包含一个分页的博客文章列表,带有类似于/博客/ 2
而且/博客/ 3
第2和第3页。如果将路由路径更改为页面/博客/ {}
,你会遇到一个问题:
- blog_list:
页面/博客/ {}
将匹配/博客/ *
; - blog_show:
/博客/{蛞蝓}
将也匹配/博客/ *
.
当两个路由匹配相同的URL时第一个加载的路由获胜。不幸的是,这意味着/博客/ yay-routing
将匹配blog_list
.没有好!
若要修复此问题,请添加要求这一{页面}
通配符可以只有匹配数字(数字):
- 注释
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/ / src / AppBundle /控制器/ BlogController.php名称空间AppBundle\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\控制器;使用Sensio赞助\包\FrameworkExtraBundle\配置\路线;类BlogController扩展控制器{/ * * *@Route(“/博客/{页面}”,name = " blog_list "需求={"页面" = " \ d + "}) * /公共函数listAction($页面){/ /……}/ * * *@Route("/blog/{slug}", name="blog_show") */公共函数showAction($鼻涕虫){/ /……}}
的\ d +
正则表达式是否匹配数字任何长度。现在:
URL | 路线 | 参数 |
---|---|---|
/博客/ 2 |
blog_list |
美元的页面 =2 |
/博客/ yay-routing |
blog_show |
美元蛞蝓 =yay-routing |
要了解其他路由要求(如HTTP方法、主机名和动态表达式),请参见如何定义路由需求.
给{占位符}一个默认值
在前面的示例中,blog_list
有一条路径页面/博客/ {}
.如果用户访问/博客/ 1
,它会匹配。但是如果他们来访/博客
,它会不匹配。只要你加入a{占位符}
到一个路线,它必须要有价值。
那么你怎么做blog_list
当用户访问时再次匹配/博客
?通过添加默认的值:
- 注释
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src / AppBundle /控制器/ BlogController.php名称空间AppBundle\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\控制器;使用Sensio赞助\包\FrameworkExtraBundle\配置\路线;类BlogController扩展控制器{/ * * *@Route(“/博客/{页面}”,name = " blog_list "需求={"页面" = " \ d + "}) * /公共函数listAction($页面=1){/ /……}}
现在,当用户访问/博客
,blog_list
路由将匹配美元的页面
将默认为1
.
高级路由实例
记住这些,看看这个高级的例子:
- 注释
- YAML
- XML
- PHP
12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
/ / src / AppBundle /控制器/ ArticleController.php/ /……类ArticleController扩展控制器{/ * * *@Route(* "/articles/{_locale}/{year}/{slug}。{_format}", * defaults={"_format": "html"}, * requirements={ * "_locale": "en|fr", * "_format": "html|rss", * "year": "\d+" * } * ) */公共函数showAction($_locale,$一年,$鼻涕虫){}}
如您所见,只有当{_locale}
URL的一部分是任意一个在
或fr
如果{一}
是一个数字。这条路由还展示了如何在占位符之间使用点而不是斜线。与此路由匹配的url可能是这样的:
/文章/ en / 2010 /我的帖子
/ / fr / 2010 / my-post.rss文章
/ / en / 2013 / my-latest-post.html文章
请注意
有时你想让你的路由的某些部分全局可配置。欧宝娱乐app下载地址Symfony通过利用服务容器参数为您提供了一种方法。详情请参阅“如何在路由中使用服务容器参数".
谨慎
路由占位符名称不能以数字开头,也不能超过32个字符。
控制器命名模式
如果使用YAML、XML或PHP路由配置,则每个路由必须有一个_controller
参数,该参数指定当路由匹配时应该执行哪个控制器。该参数使用一个简单的字符串模式,称为逻辑控制器名称, Symfon欧宝娱乐app下载地址y将其映射到特定的PHP方法和类。该模式由三个部分组成,每个部分由冒号分隔:
包:控制器:行动
例如,_controller
的价值AppBundle:博客:显示
意思是:
包 | 控制器类 | 方法名称 |
---|---|---|
AppBundle |
BlogController |
showAction () |
控制器看起来是这样的:
12 3 4 5 6 7 8 9 10 11 12
/ / src / AppBundle /控制器/ BlogController.php名称空间AppBundle\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\控制器;类BlogController扩展控制器{公共函数showAction($鼻涕虫){/ /……}}
注意,Symfony添加欧宝娱乐app下载地址了字符串控制器
到类名(博客
= >BlogController
),行动
到方法名(显示
= >showAction ()
).
你也可以使用它的全限定类名和方法来引用这个控制器:AppBundle \控制器\ BlogController:: showAction
.但是如果您遵循一些简单的约定,逻辑名称将更加简洁,并允许更多的灵活性。
提示
将实现的操作引用为__invoke ()
方法,你不必传递方法名,但可以只使用完全限定类名(例如。AppBundle \ \ BlogController控制器
).
请注意
除了使用逻辑名或全限定类名之外,Symfony还支持第三种引用控制器的方式。欧宝娱乐app下载地址这种方法只使用一个冒号分隔符(例如。service_name: indexAction
),并将控制器引用为服务(参见如何将控制器定义为服务).
加载路径
欧宝娱乐app下载地址Symfony加载应用程序的所有路由单路由配置文件:应用程序/配置/ routing.yml
.但是在这个文件中,你可以加载任何文件其他路由您需要的文件。事实上,默认情况下,Symfony从App欧宝娱乐app下载地址Bundle的注释路由配置中加载注释路由配置控制器/
目录,这是Symfony看到注释路由的方式:欧宝娱乐app下载地址
- YAML
- XML
- PHP
1 2 3 4
# app / config / routing.yml应用:资源:“@AppBundle /控制器/”类型:注释
有关加载路由的详细信息,包括如何为加载路由的路径添加前缀,请参见如何包括外部路由资源.
生成的url
路由系统还应该用于生成url。实际上,路由是一个双向系统:将URL映射到控制器,并将路由映射回URL。
要生成URL,您需要指定路由的名称(例如:blog_show
)和任何通配符(例如:Slug = my blog-post
)用于该路由的路径。有了这些信息,任何URL都可以很容易地生成:
12 3 4 5 6 7 8 9 10 11 12 13
类MainController扩展控制器{公共函数showAction($鼻涕虫){/ /……/ / /博客/我的博客帖子$url=$这->generateUrl (“blog_show”,数组(“鼻涕虫”= >“我的博客帖子”));}}
请注意
的generateUrl ()
方法中定义的控制器类只是这段代码的快捷方式:
1 2 3 4
$url=$这->容器->get (“路由器”)->生成(“blog_show”,数组(“鼻涕虫”= >“我的博客帖子”));
使用查询字符串生成url
的生成()
方法接受一个通配符值数组来生成URI。但是如果你传递了额外的参数,它们将作为查询字符串添加到URI中:
1 2 3 4 5
$这->get (“路由器”)->生成(“博客”,数组(“页面”= >2,“类别”= >S欧宝娱乐app下载地址ymfony的));/ / /博客/ 2 ?类别= Symfo欧宝娱乐app下载地址ny
从模板生成url
要在Twig内部生成url,请参阅模板文章:创建和使用模板.如果还需要用JavaScript生成url,请参见如何在JavaScript中生成路由url.
生成绝对url
默认情况下,路由器将生成相对url(例如。/博客
).从控制器,通过UrlGeneratorInterface: ABSOLUTE_URL
的第三个参数generateUrl ()
方法:
1 2 3 4
使用欧宝娱乐app下载地址\组件\路由\发电机\UrlGeneratorInterface;$这->generateUrl (“blog_show”,数组(“鼻涕虫”= >“我的博客帖子”), UrlGeneratorInterface::ABSOLUTE_URL);/ / http://www.example.com/blog/my-blog-post
请注意
生成绝对URL时使用的主机将使用当前的请求
对象。当从web上下文之外生成绝对url时(例如在控制台命令中),这是行不通的。看到如何从控制台生成url学习如何解决这个问题。
故障排除
下面是一些你在使用路由时可能会看到的常见错误:
控制器"AppBundle\Controller\BlogController::showAction()"要求你为"$slug"参数提供一个值。
当你的控制器方法有一个参数(例如。美元蛞蝓
):
1 2 3 4
公共函数showAction($鼻涕虫){/ / . .}
但是你的路线可以不有一个{蛞蝓}
通配符(例如,它是/博客/显示
).添加一个{蛞蝓}
到您的路线路径:/博客/显示/{蛞蝓}
或者给参数一个默认值(即。$slug = null
).
缺少一些必要的参数(“slug”)来为路由“blog_show”生成URL。
对象的URLblog_show
但你是不传递一个鼻涕虫
值(这是必需的,因为它有一个{蛞蝓}
)在路由路径中的通配符。为了解决这个问题,传递一个鼻涕虫
生成路由时的值:
1 2 3 4
$这->generateUrl (“blog_show”,数组(“鼻涕虫”= >“slug-value”));//或者,在Twig中/ /{{路径(blog_show,{“鼻涕虫”:“slug-value”})}}
翻译路线
欧宝娱乐app下载地址Symfony不支持根据用户语言定义不同内容的路由。在这些情况下,您可以为每个控制器定义多条路由,每种路由对应支持的语言;或者使用社区创建的任何包来实现此特性,例如欧宝下载链接JMSI18nRoutingBundle而且BeSimpleI18nRoutingBundle.
总结
路由是一种将传入请求的URL映射到应调用以处理请求的控制器函数的系统。它既允许您指定漂亮的url,又使应用程序的功能与这些url分离。路由是一种双向机制,这意味着它也应该用于生成url。