路由
编辑该页面警告:你浏览的文档欧宝体育电话欧宝娱乐app下载地址Symfony 4.2,不再维护。
读这个页面的更新版本Symf欧宝娱乐app下载地址ony 6.2(当前的稳定版本)。
路由
美丽的url是一个必须为任何严重的web应用程序。这意味着留下丑陋的urlindex . php ? article_id = 57
赞成这样/读/ intro-to-sy欧宝娱乐app下载地址mfony
。
灵活性是更重要的。如果您需要更改一个页面的URL/博客
来/欧宝app在哪里找新闻
吗?有多少链接你需要追踪和更新做出改变吗?如果你使用Symfony的路由器欧宝娱乐app下载地址,改变应该是微不足道的。
创建路线
一个路线是一个从一个URL路径映射到属性(我。e控制器)。假设你想要一个路线相匹配/博客
完全和另一个更加动态的路线可以匹配任何URL像/博客/我的帖子
或/博客/ all-about-s欧宝娱乐app下载地址ymfony
。
路线可以配置在YAML、XML、PHP或使用注释。所有格式提供相同的功能和性能,所以选择一个你喜欢。如果你选择PHP注释,一旦运行这个命令在您的应用程序添加支持:
1
美元作曲家需要注释
现在您可以配置的路线:
- 注释
- YAML
- XML
- PHP
1 2 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 32
/ / src /控制器/ BlogController.php名称空间应用程序\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\AbstractController;使用欧宝娱乐app下载地址\组件\路由\注释\路线;类BlogController扩展AbstractController{/ * * *匹配/博客到底是* *@Route(name = " /博客”“blog_list”) * /公共函数列表(){/ /……}/ * * *匹配/博客/ * *而不是/博客/料/额外部分* *@Route(“/博客/{蛞蝓}”,name = " blog_show ") * /公共函数显示(美元鼻涕虫){/ /美元料将平等的动态URL的一部分/ /如在/博客/ yay-routing,那么$蛞蝓=“yay-routing”/ /……}}
由于这两个路线:
- 如果用户进入
/博客
,第一个路线相匹配列表()
执行; - 如果用户进入
/博客/ *
第二个途径是匹配的显示()
是执行。因为路由路径/博客/{蛞蝓}
,一个美元蛞蝓
变量传递给显示()
匹配的值。例如,如果用户去/博客/ yay-routing
,然后美元蛞蝓
就等于yay-routing
。
每当你有一个{占位符}
在你的路由路径,这部分成为一个通配符:它匹配任何价值。控制器现在可以也有一个参数称为美元的占位符
(通配符和参数名称必须匹配)。
谨慎
然而,削减/
默认是忽略了占位符的值,因为路由器使用它作为分隔符之间不同的占位符。更多地了解这个,你可以阅读如何让一个“/”字符在一个路由参数。
每个路线也有一个内部的名字:blog_list
和blog_show
。这些可以是任何东西(只要每个都是独一无二的),还没有任何意义。稍后您将使用它们生成的url。
局部路由(i18n)
每个航线可以本地化提供独特的路径语言环境。欧宝娱乐app下载地址Symfony提供了一个方便的方法来声明局部线路没有重复。
- 注释
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/ / src /控制器/ CompanyController.php名称空间应用程序\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\AbstractController;使用欧宝娱乐app下载地址\组件\路由\注释\路线;类CompanyController扩展AbstractController{/ * * *@Route({*“问”:“/ over-ons”*“en”:“/关于我们”*},name = " about_us ") * /公共函数关于(){/ /……}}
当一个本地化的路线自动匹配Symfony知道应该使用哪种语言环境在请欧宝娱乐app下载地址求。这样定义路线也消除了需要重复登记的路线最大限度地减少任何bug造成的定义不一致的风险。
提示
如果应用程序使用完整的语言+领土地区(如。fr_FR
,fr_BE
),您可以使用(如语言只有在你的路线。fr
)。这可以防止需要定义多个路径当你想使用相同的路由路径共享同一语言的地区。
国际化了的应用程序的一个常见需求是前缀与一个地区所有航线。可以通过定义一个不同的前缀为每个地区(和设置一个空前缀为默认语言环境如果你喜欢它):
- YAML
- XML
- PHP
1 2 3 4 5 6 7
#配置/线路/ annotations.yaml控制器:资源:“. . / . . / src /控制器/”类型:注释前缀:en:”#不要url前缀(英文),默认语言环境问:' /问'
添加{通配符}要求
想象一下blog_list
路线将包含一个分页的博客文章的列表,这样的url/博客/ 2
和/博客/ 3
页面2和3。如果你改变路线的道路页面/博客/ {}
,你会有一个问题:
- blog_list:
页面/博客/ {}
将匹配/博客/ *
; - blog_show:
/博客/{蛞蝓}
将也匹配/博客/ *
。
当两个路线匹配相同的URL,第一个路线的加载获胜。不幸的是,这意味着/博客/ yay-routing
将匹配blog_list
。没有好!
为了解决这个问题,添加一个要求这一{页面}
通配符可以只有匹配的数字(数字):
- 注释
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21日22日23日24
/ / src /控制器/ BlogController.php名称空间应用程序\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\AbstractController;使用欧宝娱乐app下载地址\组件\路由\注释\路线;类BlogController扩展AbstractController{/ * * *@Route(“/博客/{页面}”,name = " blog_list "需求={"页面" = " \ d + "}) * /公共函数列表(美元页面){/ /……}/ * * *@Route(“/博客/{蛞蝓}”,name = " blog_show ") * /公共函数显示(美元鼻涕虫){/ /……}}
的\ d +
是一个正则表达式相匹配的数字任何长度。现在:
URL | 路线 | 参数 |
---|---|---|
/博客/ 2 |
blog_list |
美元的页面 =2 |
/博客/ yay-routing |
blog_show |
美元蛞蝓 =yay-routing |
如果你喜欢,要求在每一个占位符可以内联使用语法{placeholder_name <规定>}
。这个特性使得配置更简洁,但它可以减少路由可读性时需求是复杂的:
- 注释
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src /控制器/ BlogController.php名称空间应用程序\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\AbstractController;使用欧宝娱乐app下载地址\组件\路由\注释\路线;类BlogController扩展AbstractController{/ * * *@Route(“/博客/{页< \ d + >}”, name = " blog_list ") * /公共函数列表(美元页面){/ /……}}
了解其他路线需求——比如HTTP方法,主机名和动态表情——看到的如何定义路由需求。
给{占位符}一个默认值
在前面的例子中,blog_list
有一个路径页面/博客/ {}
。如果用户访问/博客/ 1
,它将匹配。但如果他们访问/博客
,它将不匹配。一旦你添加一个{占位符}
路线,它必须有一个值。
所以你怎么舍得blog_list
再一次匹配,当用户访问/博客
吗?通过添加一个默认的值:
- 注释
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src /控制器/ BlogController.php名称空间应用程序\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\AbstractController;使用欧宝娱乐app下载地址\组件\路由\注释\路线;类BlogController扩展AbstractController{/ * * *@Route(“/博客/{页面}”,name = " blog_list "需求={"页面" = " \ d + "}) * /公共函数列表(美元页面=1){/ /……}}
现在,当用户访问/博客
,blog_list
路线将匹配和美元的页面
默认值吗1
。
碰巧与要求,默认值也可以在每一个占位符使用内联语法{placeholder_name ? default_value}
。这个功能兼容内联需求,所以你可以内嵌在一个占位符:
- 注释
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/ / src /控制器/ BlogController.php名称空间应用程序\控制器;使用欧宝娱乐app下载地址\包\FrameworkBundle\控制器\AbstractController;使用欧宝娱乐app下载地址\组件\路由\注释\路线;类BlogController扩展AbstractController{/ * * *@Route(“/博客/{页< \ d + > ?1}", name="blog_list") */< /span>公共函数列表(美元页面){/ /……}}
提示
给一个零
默认值占位符,添加后吗?
字符(如。/博客/{页面?}
)。
列出所有你的路线
随着应用程序的增长,最终你就会有一个很多的路线!看到他们,运行:
1 2 3 4 5 6 7 8
美元php bin /控制台调试:路由器- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -名称的方法路径- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - app_lucky_number任何/幸运/数量/{马克斯}…- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
先进的路由的例子
记住这一切,看看这个先进的例子:
- 注释
- YAML
- XML
- PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/ / src /控制器/ ArticleController.php/ /……类ArticleController扩展AbstractController{/ * * *@Route(*”/文章/ {_locale} /{一}/{蛞蝓}。{_format}", * defaults={"_format": "html"}, * requirements={ * "_locale": "en|fr", * "_format": "html|rss", * "year": "\d+" * } * ) */< /span>公共函数显示(美元_locale,美元一年,美元鼻涕虫){}}
正如您所看到的,这条路如果只会匹配{_locale}
URL的一部分在
或fr
如果{一}
是一个数字。这条路还展示了如何使用占位符之间的一个点,而不是削减。的url匹配这条路线的样子:
/文章/ en / 2010 /我的帖子
/ / fr / 2010 / my-post.rss文章
/ / en / 2013 / my-latest-post.html文章
请注意
有时你想让你的某些部分全球航线可配置的。欧宝娱乐app下载地址Symfony提供了方法利用服务容器参数。阅读更多关于这个的”如何使用服务容器参数在你的路线吗”。
特殊的路由参数
如您所见,每个路由参数或最终可用默认值作为参数的控制器方法。此外,特别的有四个参数:每个添加一个独特的功能在您的应用程序:
重定向url和斜杠
从历史上看,url的UNIX约定为目录(例如添加斜杠https://example.com/foo/
)和删除它们引用文件(https://example.com/foo
)。虽然为不同内容的URL是好的,现在是很普遍的治疗作为URL相同的URL和重定向。
欧宝娱乐app下载地址Symfony遵循这种逻辑之间的重定向url有或没有斜杠(但只得到
和头
请求):
路由路径 | 如果所请求的URL/ foo |
如果所请求的URL/ foo / |
/ foo |
它匹配(200年 状态响应) |
它使一个301年 重定向到/ foo |
/ foo / |
它使一个301年 重定向到/ foo / |
它匹配(200年 状态响应) |
请注意
如果您的应用程序为每个路径(定义不同的路线/ foo
和/ foo /
)这个自动重定向不发生和正确的路线总是匹配。
控制器命名模式
的控制器
价值在你的路线有格式CONTROLLER_CLASS::方法
。
提示
指一个动作实现的__invoke ()
控制器类的方法,你不需要通过方法名称,您还可以使用完全限定类名(如。应用程序控制器\ \ BlogController
)。
生成的url
路由系统还可以生成的url。在现实中,路由是一个双向系统:将URL映射到一个控制器和一个路线回到一个URL。
生成一个URL,您需要指定路线的名称(如。blog_show
)和任何通配符(如。蛞蝓=我的博客帖子
)用于路由的路径。根据这些信息,可以生成一个URL控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13
类BlogController扩展AbstractController{公共函数显示(美元鼻涕虫){/ /……/ / /博客/我的博客帖子美元url=美元这- >generateUrl (“blog_show”,(“鼻涕虫”= >“我的博客帖子”]);}}
如果你需要从一个服务生成一个URL, type-hintUrlGeneratorInterface服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/ / src /服务/ SomeService.php使用欧宝娱乐app下载地址\组件\路由\发电机\UrlGeneratorInterface;类SomeService{私人美元路由器;公共函数__construct(UrlGeneratorInterface美元路由器){美元这- >路由器=美元路由器;}公共函数someMethod(){美元url=美元这- >路由器- >生成(“blog_show”,(“鼻涕虫”= >“我的博客帖子”]);/ /……}}
生成的url查询字符串
的生成()
方法使用通配符的数组值生成URI。但是如果你通过额外的,他们将被添加到URI查询字符串:
1 2 3 4 5
美元这- >路由器- >生成(“博客”,(“页面”= >2,“类别”= >S欧宝娱乐app下载地址ymfony的]);/ / /博客/ 2 ?类别= Symf欧宝娱乐app下载地址ony
产生局部的url
本地化的路线时,Symfony使用默认当前请求区域生成欧宝娱乐app下载地址的URL。为了生成的URL不同地区必须通过_locale
参数数组:
1 2 3 4
美元这- >路由器- >生成(“about_us”,(“_locale”= >“问”]);/ /生成:/ over-ons
从一个模板生成的url
生成的url在树枝,看到模板文章:创建和使用模板。如果您还需要生成url在JavaScript中,看到的如何在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从控制台学习如何解决这个问题。
故障排除
下面是一些常见的错误你可能会看到在处理路由:
控制器“App \控制器\ BlogController:显示()要求您提供一个值“鼻涕虫美元”的论点。
这发生在你的控制器方法有一个参数(如。美元蛞蝓
):
1 2 3 4
公共函数显示(美元鼻涕虫){/ /……}
但是你的路由路径不有一个{蛞蝓}
通配符(例如/博客/显示
)。添加一个{蛞蝓}
你的路由路径:/博客/显示/{蛞蝓}
或者给参数默认值(即。$蛞蝓=零
)。
一些强制参数丢失(“鼻涕虫”)来生成一个URL路由“blog_show”。
这意味着你想生成的URLblog_show
但你是路线不传递一个鼻涕虫
值(这是必需的,因为它有一个{蛞蝓}
通配符在路由路径。为了解决这个问题,通过一个鼻涕虫
值在生成的路线:
1 2 3 4
美元这- >generateUrl (“blog_show”,(“鼻涕虫”= >“slug-value”]);/ /或者在树枝/ /{{路径(blog_show,{“鼻涕虫”:“slug-value”})}}