第9章-链路和路由系统
链接和url在web应用程序框架中值得特别对待。这是因为应用程序的唯一入口点(前端控制器)和模板中helper的使用允许url的工作方式和外观之间的完全分离。这叫做路由。路由不仅仅是一个小工具,它是一个有用的工具,可以使web应用程序更加友好和安全。本章将告诉你在symfony应用程序中处理url所需要知道的一切:ob娱乐下载
- 路由系统是什么以及它是如何工作的
- 如何在模板中使用链接助手来启用外向url的路由
- 如何配置路由规则来改变url的外观
您还将发现一些掌握路由性能和添加最后润色的技巧。
什么是路由?
路由是一种重写url以使其更友好的机制。但是要理解为什么这很重要,您必须先花几分钟思考一下url。
url作为服务器说明
url将信息从浏览器传递到服务器,服务器需要执行用户所需的操作。例如,传统的URL包含脚本的文件路径和完成请求所需的一些参数,如下例所示:
http://www.example.com/web/controller/article.php?id=123456&format_code=6532
这个URL传递有关应用程序的体系结构和数据库的信息。开发人员通常在界面中隐藏应用程序的基础结构(例如,他们选择像“个人简介页面”这样的页面标题,而不是“QZ7.65”)。在URL中揭示应用程序内部的重要线索与这一努力相矛盾,并且有严重的缺陷:
- URL中出现的技术数据会造成潜在的安全漏洞。的值时,会发生什么情况
id
参数?这是否意味着应用程序提供了到数据库的直接接口?或者如果用户尝试了其他脚本名称,比如admin.php
,只是为了好玩?总而言之,原始url为破解应用程序提供了一种简单的方法,使用它们管理安全性几乎是不可能的。 - url的不可理解性使它们无论出现在哪里都令人不安,并且它们削弱了周围内容的影响。现在,url不仅仅出现在地址栏中。当用户将鼠标悬停在链接上时,它们就会出现,在搜索结果中也会出现。当用户查找信息时,您希望为他们提供容易理解的线索,而不是像图9-1所示的那样提供令人困惑的URL。
图9-1 - url出现在很多地方,比如在搜索结果中
- 如果必须更改一个URL(例如,如果修改了脚本名称或其参数之一),则到该URL的每个链接也必须更改。这意味着控制器结构的修改是重量级且昂贵的,这在敏捷开发中并不理想。
如果symfony不使用前端控制器模式,情况可能会更糟;ob娱乐下载也就是说,如果应用程序包含许多可从Internet访问的脚本,在许多目录中,例如:
http://www.example.com/web/gallery/album.php?name=my%20holidays http://www.example.com/web/weblog/public/post/list.php http://www.example.com/web/general/content/page.php?name=about%20us
在这种情况下,开发人员将需要将URL结构与文件结构相匹配,当其中任何一种结构发生变化时,都会导致维护的噩梦。
url作为接口的一部分
路由背后的思想是将URL视为接口的一部分。应用程序可以格式化URL以将信息传递给用户,用户可以使用URL访问应用程序的资源。
这在symfony应用程序中是可能的,因ob娱乐下载为呈现给最终用户的URL与执行请求所需的服务器指令无关。相反,它与所请求的资源相关,并且可以自由格式化。例如,symfony可以理解ob娱乐下载以下URL,并让它显示与本章中显示的第一个URL相同的页面:
http://www.example.com/articles/finance/2006/activity-breakdown.html
好处是巨大的:
- url实际上是有意义的,它们可以帮助用户判断链接后面的页面是否包含他们所期望的内容。链接可以包含关于它返回的资源的其他详细信息。这对于搜索引擎的结果特别有用。此外,URL有时出现时没有提到页面标题(想想当您在电子邮件消息中复制URL时),在这种情况下,它们必须有自己的含义。用户友好型URL示例如图9-2所示。
图9-2 - url可以传递关于页面的附加信息,比如发布日期
- 写在纸质文档中的url更容易输入和记忆。如果贵公司网站显示为
http://www.example.com/controller/web/index.jsp?id=ERD4
在你的名片上,它可能不会有很多访客。 URL可以成为自己的命令行工具,以直观的方式执行操作或检索信息。对于高级用户来说,提供这种可能性的应用程序使用起来更快。
//结果列表:添加一个新标签来缩小结果列表http://del.icio.us/tag/symfony+ajax //用户配置文件页面:更改名称以获得另一个用户配置文件httob娱乐下载p://www.askeet.com/user/francois
您可以单独更改URL格式和操作名称/参数,只需一次修改。这意味着您可以先开发,然后格式化url,而不会完全搞乱您的应用程序。
- 即使当您重新组织应用程序的内部结构时,url对于外部世界也可以保持不变。它使url持久,这是必须的,因为它允许在动态页面上添加书签。
- 搜索引擎倾向于跳过动态页面(以
. php
,asp
,等等)当他们索引网站时。因此,您可以对url进行格式化,使搜索引擎认为它们正在浏览静态内容,即使它们遇到动态页面,这样就可以更好地为您的应用程序页面建立索引。 - 这样更安全。任何无法识别的URL都将被重定向到开发人员指定的页面,用户无法通过测试URL来浏览web根文件结构。请求调用的实际脚本名称及其参数将被隐藏。
提供给用户的url与实际脚本名称和请求参数之间的对应关系是由路由系统实现的,该系统基于可以通过配置修改的模式。
请注意
资产呢?幸运的是,资产(图像、样式表和JavaScript)的url在浏览过程中并不经常出现,因此不需要对它们进行路由。在syob娱乐下载mfony中,所有资产都位于web /
目录,它们的URL与它们在文件系统中的位置相匹配。但是,您可以通过在资产帮助器中使用生成的URL来管理动态资产(由操作处理)。例如,要显示动态生成的图像,使用image_tag (url_for('验证码/形象?关键= '键)美元。)
.
工作原理
ob娱乐下载Symfony断开外部URL及其内部URI的连接。两者之间的对应关系由路由系统实现。为了简化操作,symfony为内部uri使ob娱乐下载用了与常规url非常相似的语法。清单9-1给出了一个示例。
清单9-1 -外部URL和内部URI
//内部URI语法/ [?param1=value1][¶m2=value2][¶m3=value3]…//示例内部URI,它永远不会出现在最终用户article/permalink?year=2006&subject=finance&title=activity-breakdown //示例外部URL,显示给最终用户http://www.example.com/articles/finance/2006/activity-breakdown.html
路由系统使用一个特殊的配置文件routing.yml
,可以定义路由规则。考虑清单9-2所示的规则。它定义了一个像这样的模式文章/ * / * / *
并命名与通配符匹配的内容片段。
清单9-2 -路由规则示例
Article_by_title: url: articles/:subject/:year/:title.html参数:{模块:文章,动作:永久链接}
发送到symfony应用程序的每个请求都首先由路ob娱乐下载由系统进行分析(这很简单,因为每个请求都由单个前端控制器处理)。路由系统查找请求URL和路由规则中定义的模式之间的匹配。类中定义的通配符将成为请求参数并与之合并参数:
关键。在清单9-3中查看它的工作原理。
清单9-3 -路由系统解释传入的请求url
//用户键入(或点击)这个外部URL http://www.example.com/articles/finance/2006/activity-breakdown.html //前端控制器看到它匹配article_by_title规则//路由系统创建以下请求参数'module' => 'article' 'action' => 'permalink' 'subject' => 'finance' 'year' => '2006' 'title' => 'activity-breakdown'
提示
的. html
外部URL的扩展是一个简单的装饰,路由系统会忽略它。它唯一的兴趣是使动态页面看起来像静态页面。你将在本章后面的“路由配置”部分看到如何激活这个扩展。
请求然后传递给永久链接
的行动文章
模块,它在请求参数中包含所有必需的信息,以确定要显示哪篇文章。
但这种机制也必须反过来起作用。要使应用程序在其链接中显示外部url,必须向路由系统提供足够的数据,以确定应用哪个规则。也不能直接使用<一>
标签——这将完全绕过路由——但是使用一个特殊的助手,如清单9-4所示。
清单9-4 -路由系统在模板中格式化出站url
// url_for() helper将内部URI转换为外部URL< a href =“< ?PHP echo url_for('article/permalink?subject=finance&year=2006&title=activity-breakdown') ?>">请点击这里< / >// helper看到URI匹配article_by_title规则//路由系统从中创建一个外部URL=> “http://www.example.com/articles/finance/2006/activity-breakdown.html”>请点击这里< / >// link_to() helper直接输出一个超链接//避免混合PHP和HTML<?php回声link_to(“点击这里”,的文章/永久链接吗?主题= finance&year = 2006标题= activity-breakdown ')? >//在内部,link_to()将调用url_for(),因此结果是相同的=> “http://www.example.com/articles/finance/2006/activity-breakdown.html”>请点击这里< / >
因此路由是一种双向机制,只有在使用link_to ()
帮助格式化您的所有链接。
URL重写
在深入了解路由系统之前,有一件事需要澄清。在前一节给出的例子中,没有提到前端控制器(index . php
或myapp_dev.php
)在内部uri中。前端控制器(而不是应用程序的元素)决定环境。因此,所有链接都必须与环境无关,并且前端控制器名称永远不能出现在内部uri中。
生成的url示例中也没有脚本名称。这是因为在默认情况下,生成的url在生产环境中不包含任何脚本名称。的no_script_name
参数。settings.yml
文件精确地控制了前端控制器名称在生成的url中的外观。设置为从
,如清单9-5所示,链接助手输出的url将在每个链接中提到前端控制器脚本名称。
清单9-5 -在url中显示前端控制器名称,在应用程序/ myapp / config / settings.yml
Prod: .settings: no_script_name:关闭
现在,生成的url看起来是这样的:
http://www.example.com/index.php/articles/finance/2006/activity-breakdown.html
在除生产环境外的所有环境中no_script_name
参数设置为从
默认情况下。例如,当您在开发环境中浏览应用程序时,前端控制器名称总是出现在url中。
http://www.example.com/myapp_dev.php/articles/finance/2006/activity-breakdown.html
在生产中,no_script_name
设置为在
,因此url只显示路由信息,更加用户友好。没有技术信息。
http://www.example.com/articles/finance/2006/activity-breakdown.html
但是应用程序如何知道要调用哪个前端控制器脚本呢?这就是URL重写的用武之地。web服务器可以配置为在URL中没有脚本时调用给定脚本。
在Apache中,一旦您拥有mod_rewrite
扩展激活。每个symfob娱乐下载ony项目都有一个. htaccess
文件,它添加mod_rewrite
属性的服务器配置web /
目录中。该文件的默认内容如清单9-6所示。
清单9-6 - Apache的默认重写规则,在myproject / web / . htaccess
RewriteEngine在#我们用.something #跳过所有文件注释以下3行以允许在路由中使用句点\.html$ RewriteRule .* - [L] #我们检查。html版本是否在这里(缓存)RewriteRule ^$ index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] RewriteCond %{REQUEST_FILENAME} !- f#不,所以我们重定向到我们的前端web控制器RewriteRule ^(.*)$ index.php [QSA,L]
web服务器检查它接收到的url的形状。如果URL不包含后缀,并且页面没有可用的缓存版本(第12章讨论缓存),那么请求将被传递给index . php
.
提示
要允许在路由中使用句点,只需在.htaccess文件中注释前两个重写条件和第一个重写规则。
然而,web /
symfony项目的目录在项目ob娱乐下载的所有应用程序和环境之间共享。这意味着web目录中通常有多个前端控制器。例如,一个项目有一个前端
和一个后端
应用程序,以及dev
而且刺激
环境中包含四个前端控制器脚本web /
目录:
Index.php // prod中的前端frontend_dev.php // dev中的前端backend.php // prod中的后端backend_dev.php // dev中的后端
mod_rewrite设置只能指定一个默认脚本名。如果将所有应用程序和环境的no_script_name设置为on,则所有url将被解释为对前端
应用于刺激
环境。这就是为什么您只能有一个应用程序和一个环境来利用给定项目的URL重写。
提示
有一种方法可以让多个应用程序没有脚本名。只需在web根目录中创建子目录,并在其中移动前端控制器。改变SF_ROOT_DIR
常量定义,并创建. htaccess
每个应用程序所需的URL重写配置。
链接助手
由于路由系统的原因,您应该使用链接助手而不是常规的链接助手<一>
模板中的标签。不要将其视为麻烦,而是将其视为保持应用程序整洁和易于维护的机会。此外,链接助手提供了一些你不想错过的非常有用的快捷方式。
超链接、按钮和表单
你们已经知道了link_to ()
帮手。它输出一个符合xhtml的超链接,并期望有两个参数:可以单击的元素和它所指向的资源的内部URI。如果需要按钮而不是超链接,请使用button_to ()
帮手。控件的值也有一个帮助器来管理行动
属性。你将在下一章学到更多关于表单的知识。清单9-7显示了一些链接助手的例子。
清单9-7 -链接助手<一>
,<输入>
,< >形式
标签
//字符串上的超链接<?php回声link_to(“我的文章”,“文章/读?标题= Finance_in_France ')? >=> “/路由/ url / / Finance_in_France”>我的文章< / >//图像上的超链接<?php回声link_to(image_tag(“read.gif”),“文章/读?标题= Finance_in_France ')? >=> “/路由/ url / / Finance_in_France”> < img src =“遗产/图片/ read.gif”/ > < / >//按钮标签<?php回声button_to(“我的文章”,“文章/读?标题= Finance_in_France ')? >=> <输入值=“我的文章”类型=“按钮”onclick =“document.location.href = /路由/ url / / Finance_in_France”;“/>//表单标签<?php回声form_tag(“文章/读?标题= Finance_in_France ')? >=>
链接助手可以接受内部uri和绝对url(从http://
,路由系统跳过)和锚。注意,在实际应用程序中,内部uri是用动态参数构建的。清单9-8显示了所有这些情况的示例。
清单9-8 -链接助手接受的url
//内部URI<?php回声link_to(“我的文章”,“文章/读?标题= Finance_in_France ')? >=> “/路由/ url / / Finance_in_France”>我的文章< / >//带有动态参数的内部URI<?php回声link_to(“我的文章”,“文章/读?标题= '.美元的文章->getTitle())? >//带有锚的内部URI<?php回声link_to(“我的文章”,“文章/读?title = Finance_in_France # foo ')? >=> “/ / url路由到/ Finance_in_France # foo”>我的文章< / >//绝对URL<?php回声link_to(“我的文章”,“http://www.example.com/foobar.html”)? >=> “http://www.example.com/foobar.html”>我的文章< / >
链接助手选项
如第7章所述,helper接受一个额外的选项参数,它可以是一个关联数组或字符串。对于链接助手也是如此,如清单9-9所示。
清单9-9 - Link helper接受附加选项
//作为关联数组的附加选项<?php回声link_to(“我的文章”,“文章/读?标题= Finance_in_France ',数组(“类”= >“foobar”,“目标”= >“平等”))? >//作为字符串的附加选项(相同的结果)<?php回声link_to(“我的文章”,“文章/读?标题= Finance_in_France ',“阶级= foobar目标=平等”)? >=> “/路由/ url / / Finance_in_France”类=“foobar”目标=“平等”>我的文章< / >
你也可以为链接助手添加一个特定于symfony的选项:ob娱乐下载确认
而且弹出
.第一个在点击链接时显示一个JavaScript确认对话框,第二个在一个新窗口中打开链接,如清单9-10所示。
清单9-10 -“确认”
而且“弹出”
链接助手的选项
<?php回声link_to(“delete item”,“项目/删除?id = 123,confirm=你确定吗?)? >=> "return confirm('Are you sure?');"href =“/ / url路由/ html /删除/ 123.”>删除项< / ><?php回声link_to(“添加到购物车”,shoppingCart /补充的吗?id = 100,“弹出= true”)? >=> “window.open (this.href);返回false;“href =“/ fo_dev.php / shoppingCart /添加html / id / 100.”>添加到购物车<?php回声link_to(“添加到购物车”,shoppingCart /补充的吗?id = 100,数组(“弹出”= >数组(“popupWindow”,'宽度= 310,高度= 400 = 320,最高= 0的)))? >=> “window.open (this.href, popupWindow”、“宽= 310,高= 400,左= 320,最高= 0”),返回false;”href =“/ fo_dev.php / shoppingCart /添加html / id / 100.”>添加到购物车
这些选项可以组合在一起。
假的GET和POST选项
有时web开发人员使用GET请求来实际执行POST。例如,考虑以下URL:
http://www.example.com/index.php/shopping_cart/add/id/100
此请求将通过向存储在会话或数据库中的购物车对象添加项目来更改应用程序中包含的数据。这个URL可以被搜索引擎添加书签、缓存和索引。想象一下,如果使用这种技术,数据库或网站的指标可能会发生什么糟糕的事情。事实上,这个请求应该被认为是POST请求,因为搜索引擎机器人在索引时不做POST请求。
ob娱乐下载Symfony提供了一种将调用转换为对象的方法link_to ()
或button_to ()
helper转换为一个实际的POST。只要加一个帖子= true
选项,如清单9-11所示。
清单9-11 -创建链接调用POST请求
<?php回声link_to(“去购物车”,shoppingCart /补充的吗?id = 100,“帖子= true”)? >=> "f = document.createElement('form');document.body.appendChild (f);f.method = 'POST';F.action = this.href;f.submit(),返回false;”href =“/ shoppingCart /添加html / id / 100.”>去购物车
这<一>
标签有一个href
属性,而不支持JavaScript的浏览器,如搜索引擎机器人,将遵循该链接执行默认的GET。所以你也必须限制你的动作只响应POST方法,在动作开始时添加如下内容:
这个美元->forward404If(美元的请求->getMethod()! = sfRequest::帖子);
只是要确保不要在位于表单中的链接上使用此选项,因为它会生成自己的链接< >形式
标签。
将实际发布数据的链接标记为POST是一个好习惯。
强制请求参数为GET变量
根据路由规则,变量作为参数传递给alink_to ()
被转换成模式。的内部URI中,如果没有匹配的规则routing.yml
文件中,默认规则转换模块/行动?键=值
成/模块/行动/键/值
,如清单9-12所示。
清单9-12 -默认路由规则
<?php回声link_to(“我的文章”,“文章/读?标题= Finance_in_France ')? >=> / /读/标题/ Finance_in_France条”>我的文章< / >
如果您实际上需要保留GET语法——让请求参数在?key=value形式下传递——您应该将需要强制的变量放在URL参数之外query_string
选择。所有的链接助手都接受这个选项,如清单9-13所示。
清单9-13 -使用query_string
选项
<?php回声link_to(“我的文章”,/读条的,数组(“query_string”= >“标题= Finance_in_France”))? >=> " / /读条吗?标题= Finance_in_France”>我的文章< / >
请求参数显示为GET变量的URL可以由客户机端的脚本和$ _GET
而且$ _REQUEST
服务器端变量。
侧边栏
资产助手
第7章介绍了资产助手image_tag ()
,stylesheet_tag ()
,javascript_include_标记()
,它允许您在响应中包含图像、样式表或JavaScript文件。路由系统不处理这些资源的路径,因为它们链接到实际位于公共web目录下的资源。
您不需要提到资产的文件扩展名。ob娱乐下载Symfony自动添加. png
,. js
,或. css
图像、JavaScript或样式表助手调用。同样,symob娱乐下载fony将自动在/图片/ web /遗产
,web / js /
,web / css /
目录。当然,如果您想包含特定的文件格式或来自特定位置的文件,只需使用完整的文件名或完整的文件路径作为参数。不需要指定一个alt
如果媒体文件具有显式名称,则属性,因为symfony将为您确定它。ob娱乐下载
<?php回声image_tag(“测试”)? ><?php回声image_tag(“test.gif”)? ><?php回声image_tag(“/ my_images / test.gif”)? >=> “遗产/图片/ test.png”alt =“测试”/> “遗产/图片/ test.gif”alt =“测试”/> “/ my_images / test.gif”alt =“测试”/>
要固定图像的大小,请使用大小
属性。它需要一个宽度和高度(以像素为单位),用x
.
<?php回声image_tag(“测试”,“大小= 100 x20”))? >=> “遗产/图片/ test.png”alt =“测试”宽度=“100”身高=“20”/>
如果您希望资产包含在< >头
部分(用于JavaScript文件和样式表),您应该使用use_stylesheet ()
而且use_javascript ()
模板中的helper,而不是_tag ()
布局中的版本。它们将资产添加到响应中,并且这些资产包含在> < /头
标记被发送到浏览器。
使用绝对路径
默认情况下,链接和资产助手生成相对路径。若要强制输出为绝对路径,请设置绝对
选项真正的
,如清单9-14所示。此技术对于在电子邮件消息、RSS提要或API响应中包含链接非常有用。
清单9-14 -获取绝对url而不是相对url
<?php回声url_for(“文章/读?标题= Finance_in_France ')? >= >' / / url / / Finance_in_France路由的<?php回声url_for(“文章/读?标题= Finance_in_France ',真正的)? >= >“http://www.example.com/routed/url/to/Finance_in_France”<?php回声link_to(“金融”,“文章/读?标题= Finance_in_France ')? >=> “/路由/ url / / Finance_in_France”金融> < / ><?php回声link_to(“金融”,“文章/读?标题= Finance_in_France ',“绝对= true”)? >=> “http://www.example.com/routed/url/to/Finance_in_France”金融> < / >//同样适用于资产helper<?php回声image_tag(“测试”,“绝对= true”)? ><?php回声javascript_include_tag(“myscript”,“绝对= true”)? >
侧边栏
邮件助手
如今,电子邮件收集机器人在网络上徘徊,你不能在网站上显示电子邮件地址而不成为垃圾邮件的受害者。这就是symfony提供ob娱乐下载mail_to ()
帮手。
的mail_to ()
Helper接受两个参数:实际的电子邮件地址和应该显示的字符串。其他选项接受编码
参数来输出一些非常不可读的HTML内容,浏览器可以理解,但机器人不能。
<?php回声mail_to(“myaddress@mydomain.com”,“接触”)? >=> “mailto: myaddress@mydomain.com > < / > <联系吗?php回声mail_to(“myaddress@mydomain.com”,“接触”,'编码=真正的')? >=> # 109; & # x61;…& # 111; & # x6d; " > & # x63; & # x74;…e # 115; & # x73; < / >
编码的电子邮件消息由随机十进制和十六进制实体编码器转换的字符组成。这个技巧暂时阻止了大多数地址收集垃圾邮件机器人,但请注意,收集技术正在迅速发展。
路由配置
路由系统做两件事:
- 它解释传入请求的外部URL并将其转换为内部URI,以确定模块/操作和请求参数。
- 它将链接中使用的内部uri格式化为外部url(前提是您使用链接帮助程序)。
转换基于一组路由规则。这些规则存储在routing.yml
位于应用程序中的配置文件配置/
目录中。清单9-15显示了与每个symfony项目捆绑在一起的默认路由规则。ob娱乐下载
清单9-15 -默认路由规则,在myapp / config / routing.yml
# default规则主页:url: / param:{模块:default,动作:index} default_symfony: url: /symfony/:acob娱乐下载tion/* param:{模块:default} default_index: url: /:模块param:{动作:index} default: url: /:模块/:action/*
规则和模式
路由规则是外部URL和内部URI之间的双射关联。一个典型的规则由以下组成:
- 一个唯一的标签,这是易读性和速度,并可由链接助手使用
- 要匹配的模式(
url
键) - 请求参数值数组(
参数
键)
模式可以包含通配符(用星号*表示)和命名通配符(以冒号:)。与命名通配符的匹配成为请求参数值。例如,默认的
在清单9-15中定义的rule将匹配任何URL/ foo / bar
,并设置模块
参数喷火
和行动
参数酒吧
.在default_ob娱乐下载symfony
规则,ob娱乐下载
是关键字,并且行动
命名为通配符参数。
路由系统解析routing.yml
从上到下的文件,并在第一个匹配处停止。这就是为什么您必须在默认规则之上添加自己的规则。例如,URL/ foo / 123
匹配清单9-16中定义的两个规则,但symfony首先进行测试ob娱乐下载my_rule:
,当该规则匹配时,它甚至不测试默认值:
一个。方法处理该请求mymodule里/ myaction
行动与酒吧
设置为123
(而不是由foo / 123
行动)。
清单9-16 -从上到下解析规则
My_rule: url: /foo/:bar param: {module: mymodule, action: myaction} #默认规则default: url: /:module/:action/*
请注意
创建新动作时,并不意味着必须为其创建路由规则。如果默认的模块/操作模式适合您,那么请忘记routing.yml
文件。但是,如果您希望自定义操作的外部URL,则可以在默认规则之上添加一个新规则。
清单9-17显示了为文章/读取操作更改外部URL格式的过程。
清单9-17 -更改对象的外部URL格式/读条
行动
<?php回声url_for(“文章/读?id = 123)? >= > / /阅读/身份证/条123//默认格式//将其改为/article/123,在开头添加一条新规则//你的routing.ymlArticle_by_id: url: /article/:id{模块:文章,动作:阅读}
问题是article_by_id
属性的所有其他操作中断了缺省路由文章
模块。事实上,一个URL文章/删除
将匹配此规则而不是默认的
一,并调用读
行动与id
设置为删除
而不是删除
行动。要解决这个困难,必须添加一个模式约束,以便article_by_id
规则只匹配id
通配符为整数。
模式的约束
当一个URL可以匹配多个规则时,您必须通过向模式添加约束或需求来细化规则。需求是规则匹配时必须用通配符匹配的一组正则表达式。
例如,修改article_by_id
规则,以便它只匹配id
参数为整数时,在规则中增加一行,如清单9-18所示。
清单9-18 -向路由规则添加需求
Article_by_id: url: /article/:id参数:{模块:文章,动作:读取}要求:{id: \d+}
现在一个文章/删除
URL不能匹配article_by_id
不再是规则,因为“删除”
字符串不满足要求。因此,路由系统将继续在以下规则中寻找匹配项,最终找到匹配项默认的
规则。
侧边栏
永久链接
路由的一个好的安全准则是隐藏主键,并用尽可能重要的字符串替换它们。如果您想通过标题而不是ID来访问文章,该怎么办呢?它将使外部url看起来像这样:
http://www.example.com/article/Finance_in_France
在这种情况下,需要创建一个新的永久链接
操作,该操作将使用鼻涕虫
参数,而不是id
一,并为它添加一个新规则:
Article_by_id: url: /article/:id参数:{模块:文章,动作:读取}要求:{id: \d+} article_by_slug: url: /article/:slug参数:{模块:文章,动作:永久链接}
的永久链接
Action需要从标题中确定所请求的文章,因此模型必须提供适当的方法。
公共函数executePermalink(){美元的文章= ArticlePeer::retrieveBySlug(这个美元->getRequestParameter(“鼻涕虫”);这个美元->forward404Unless(美元的文章);//如果没有匹配的文章显示404这个美元->文章=美元的文章;//将对象传递给模板}
的链接也需要替换读
控件的链接永久链接
第一,允许正确格式化内部uri。
/ /替换<?php回声link_to(“我的文章”,“文章/读?id = '.美元的文章->getId())? >/ /<?php回声link_to(“我的文章”,的文章/永久链接吗?蛞蝓= '.美元的文章->getSlug())? >
多亏了需求
行,一个外部URL/文章/ Finance_in_France
匹配article_by_slug
规则,即使article_by_id
规则首先出现。
注意,由于文章将通过slug检索,因此应该向鼻涕虫
中的列。文章
模型描述以优化数据库性能。
设置默认值
即使没有定义参数,也可以为命名通配符提供默认值以使规则生效。中设置默认值参数:
数组中。
例如,article_by_id
规则不匹配,如果id
参数未设置。您可以强制执行,如清单9-19所示。
清单9-19 -设置通配符的默认值
Article_by_id: url: /article/:id参数:{模块:文章,动作:读取,id: 1}
默认参数不需要是模式中的通配符。在清单9-20中,显示
参数的值为真正的
,即使URL中不存在。
清单9-20 -设置请求参数的默认值
Article_by_id: url: /article/:id参数:{模块:文章,动作:读取,id: 1,显示:true}
如果你仔细看,就会发现文章
而且读
也是默认值模块
而且行动
模式中没有变量。
提示
属性可以为所有路由规则定义默认参数sf_routing_default
配置参数。例如,如果您希望所有规则都有一个主题
参数设置为默认的
默认情况下,添加该行sfConfig::set('sf_routing_defaults', array('theme' => 'default'));
到您的应用程序config。
.
使用规则名加速路由
如果规则标签前面有@符号,链接助手接受一个规则标签,而不是模块/操作对,如清单9-21所示。
清单9-21 -使用规则标签而不是模块/动作
<?php回声link_to(“我的文章”,“文章/读?id = '.美元的文章->getId())? >//也可以写成<?php回声link_to(“我的文章”,“@article_by_id ?id = '.美元的文章->getId())? >
这种方法有利有弊。优点如下:
- 内部uri的格式化速度要快得多,因为symfony不需要浏览所有规则来找到与链接匹配的规则。ob娱乐下载在一个具有大量路由超链接的页面中,如果使用规则标签而不是模块/操作对,将会显著提高性能。
- 使用规则标签有助于抽象操作背后的逻辑。如果您决定更改操作名称但保留URL,则只需在
routing.yml
锉就够了。所有的link_to ()
在没有进一步更改的情况下,调用仍然可以工作。 - 使用规则名,调用的逻辑更加明显。即使您的模块和操作有显式的名称,调用它通常更好
@display_article_by_slug
比文章/显示
.
另一方面,缺点是添加新的超链接变得不那么明显,因为您总是需要引用routing.yml
文件,以确定操作将使用哪个标签。
最佳选择取决于项目。从长远来看,这取决于你。
提示
在测试期间(在dev
environment),如果你想在浏览器中检查哪个规则匹配了给定的请求,开发web调试工具栏的“logs and msgs”部分,并寻找指定“匹配路由XXX”的行。你将在第16章找到更多关于web调试模式的信息。
添加.html扩展名
比较这两个url:
http://myapp.example.com/article/Finance_in_France http://myapp.example.com/article/Finance_in_France.html
即使是同一个页面,用户(和机器人)也可能因为URL的不同而看到不同的页面。第二个URL会唤起一个有深度和组织良好的静态页面的web目录,这正是搜索引擎知道如何索引的那种网站。
要为路由系统生成的每个外部URL添加后缀,请更改后缀
应用价值settings.yml
,如清单9-22所示。
清单9-22 -为所有url设置后缀,在myapp / config / settings.yml
Prod: .settings:后缀:.html
默认后缀设置为句点(.
),这意味着除非您指定后缀,否则路由系统不会添加后缀。
有时需要为唯一的路由规则指定后缀。在这种情况下,直接在related中写后缀url:
线路routing.yml
如清单9-23所示。那么全局后缀将被忽略。
清单9-23 -为一个URL设置后缀,inmyapp / config / routing.yml
{模块:文章,动作:列表}article_list_feed: url: /latest_articles。RSS参数:{模块:文章,动作:列表,类型:提要}
不使用routing.yml创建规则
与大多数配置文件一样,routing.yml
是定义路由规则的解决方案,但不是唯一的解决方案。可以在PHP中定义规则,也可以在应用程序中定义规则config。
文件或在前端控制器脚本,但之前调用调度()
,因为该方法根据当前路由规则确定要执行的动作。在PHP中定义规则授权您根据配置或其他参数创建动态规则。
处理路由规则的对象是sfRouting
单例。它可以从代码的每个部分通过要求获得sfRouting: getInstance ()
.它的prependRoute ()
方法中定义的现有规则之上添加一个新规则routing.yml
.它需要四个参数,这些参数与定义规则所需的参数相同:路由标签、模式、默认值的关联数组和用于需求的另一个关联数组。例如,路由。清单9-18所示的yml规则定义等价于清单9-24所示的PHP代码。
清单9-24 -在PHP中定义规则
sfRouting::getInstance()->prependRoute(“article_by_id”,//路由名' / /条id”,//路由模式数组(“模块”= >“文章”,“行动”= >“读”),//默认值数组(“id”= >'\ d+ '),/ /要求);
sfRouting单例还有其他手工处理路由的有用方法:clearRoutes ()
,hasRoutes ()
,getRoutesByName ()
等等。请参阅API文档(欧宝官网下载app< a href ="http://www.symfony-project.org/api/1_0/">/ api / 1 _0 /),以了解更多。
提示
一旦您开始完全理解本书中提出的概念,您可以通过浏览在线API文档或symfony源代码来加深对框架的理解。欧宝官网下载appob娱乐下载并不是symfony的所有调整和参数都可以在本书中描述。ob娱乐下载然而,在线文档是无限的欧宝官网下载app。
处理动作中的路由
如果您需要检索关于当前路由的信息——例如,准备一个未来的“返回到页面xxx”链接——您应该使用sfRouting对象的方法。类返回的urigetCurrentInternalUri ()
方法的调用中可以使用link_to ()
helper,如清单9-25所示。
清单9-25 -使用sfRouting
获取当前路由信息
//如果你需要一个URLhttp:/ / myapp.example.com/article/21//在article/read动作中使用以下语句美元的uri= sfRouting::getInstance()->getCurrentInternalUri();= >文章/读吗?id =21美元的uri= sfRouting::getInstance()->getCurrentInternalUri(真正的);= > @article_by_id吗?id =21美元的统治= sfRouting::getInstance()->getCurrentRouteName();= > article_by_id//如果你只需要当前模块/动作名,//记住它们是实际的请求参数美元的模块=这个美元->getRequestParameter(“模块”);美元的行动=这个美元->getRequestParameter(“行动”);
如果您需要在操作中将内部URI转换为外部URL—就像url_for ()
在模板中使用genUrl ()
方法,如清单9-26所示。
清单9-26 -使用sfController
转换内部URI
美元的uri=“文章/读?id = 21 ';$ url=这个美元->getController()->genUrl(美元的uri);= > / /条21$ url=这个美元->getController()->genUrl(美元的uri,真正的);= > http:/ / myapp.example.com/article/21
总结
路由是一种双向机制,旨在允许格式化外部url,使它们更加用户友好。URL重写是必需的,以允许在每个项目的一个应用程序的URL中省略前端控制器名称。如果想让路由系统双向工作,每次需要在模板中输出URL时都必须使用链接助手。的routing.yml
文件配置路由系统的规则,并使用优先级和规则要求的顺序。的settings.yml
该文件包含关于外部url中前端控制器名称和可能后缀的附加设置。
本作品在GFDL许可下获得许可。