漂亮的URL地址對任何重要的網絡應用都是絕對必要的。這意味著要拋棄像index.php?article_id=57這樣的URL地址,使用一些像/read/intro-to-symfony這樣的URL地址。
更為重要的是靈活性。如果你要改變一個頁面的URL地址從/blog到/news的話,你將要查找出多少鏈接,然后再對它們修改呢?
Symfony2的路由器(router)將讓你定義創新的URL地址,可以映射到你的應用的不同區域。本章結束后,你將可以:
? 創建復雜的路由映射到控制器(controllers)
? 在模板和控制器中產生URL地址
? 從bundles中(或者其它任何地方)加載路由資源
? 調試你的路由
一個路由(A route)是一個從URL路徑到控制器(controller)的映射。例如,假設你想要匹配任何像/blog/my-post或者/blog/all-about-symfony的URL地址,然后再發送它給一個可以查看以及渲染那個博客內容的控制器(controller)。這個路由很簡單:
# app/config/routing.yml blog_show: path: /blog/{slug} defaults: { _controller: AcmeBlogBundle:Blog:show }新特性在2.2版本中:在symfony2.2中path選項是新的,pattern在老版本中使用
被路由blog_show定義的路徑起到像/blog/*的效果,通配符被指定為slug。對于URL/blog/my-blog-post,slug變量獲得my-blog-post的值,并且在你的控制器中依然可以繼續使用(keep reading)。
_controller參數是一個特殊鍵,它告訴Symfony 當一個URL地址匹配這個路由時,哪個控制器(controller)將被執行。_controller字符被稱作邏輯名稱。它遵守一種指向一個特殊PHP類和方法的模式:
恭喜你!你已經創建了你的第一個路由而且將它連接連接到了一個控制器。現在當你訪問/blog/my-post 時,showAction 控制器將被執行且$slug 變量將和my-post進行比較。
這是Symfony2 路由器的目標:將一個請求的URL映射到一個控制器。一路上,你將學習多種技巧,即使映射的是最復雜的URL,也可以相當的容易。
當你的應用程序被請求,它包含一個指向客戶端正在請求的準確資源。這個地址叫做URL地址,可以是/contact,/blog/read-me,或者其它的地址。例如采取以下http請求:
Symfony2 路由系統的目標是解析URL然后確定哪個控制器將被執行。整個過程看起來像這樣:
The routing layer is a tool that translates the incoming URL into a specific controller to execute.
路由層是一個工具,它轉換輸入的URL到將要執行的對應控制器。
Symfony 從一個路由配置文件中為你的應用程序加載所有的路由。路由配置文件常常是app/config/routing.yml,但是通過應用程序配置文件也可以被配置成XML或PHP格式的。
雖然所有路由從一個單獨的文件被加載,但是更普遍的做法是包含額外的路由資源。可以這樣做,只要指出了包含了外部文件的主路由配置文件。參考 the Including External Routing Resources 章節以獲得更多信息。
定義一個路由規則很簡單,一個標準的應用會有很多的路由規則。一個基本的路由規則僅僅由兩部分組成:匹配的路徑和默認的數組:
這條路由規則匹配主頁(/),映射它到 AcmeDemoBundle:Main:homepage 控制器。_controller 字符被Symfony2轉換成一個實際的PHP函數,然后執行。那個過程將在控制器命名模式章節中做簡短的解釋。
當然,路由系統支持很多有趣的路由規則。很多路由規則將包含一個或多個被稱作通配符的占位符:
路徑將匹配任何類似 /blog/* 的地址。更棒的是,和{slug}占位符匹配的值將可以在控制器中使用。換句話說,如果URL地址是 /blog/hello-world,值為hello-world的$slug變量將可以在控制器中使用。例如,這可以被用來加載匹配那個字符的博客文章。路徑將不會簡單地匹配 /blog。那是因為,默認地,所有占位符是必需的。通過向默認數組添加一個占位符這種情況可以改善。
讓事情更加令人激動,為這個虛構的博客應用添加一個新的路由規則,它可以顯示所有有效的博客文章列表。
到目前為止,這條路由規則是盡可能的簡單-它不包含占位符而且只匹配確切的URL地址 /blog。但是如果你需要這條路由規則支持分頁該怎么辦,以及 /blog/2 在哪里顯示第二頁的博客實體?更新路由規則使其有一個新的{page}占位符。
像之前的{slug}占位符,{page}匹配的值也可以在你的控制器中使用。它的值被用來確定哪個博客文章集合將顯示在給定的頁面上。但是等等!因為占位符默認是必須的,這條路由規則將不再簡單匹配/blog。反而,要看blog的頁面1,你需要使用URL地址 /blog/1 !因為對一個體驗良好的網絡應用,那樣是不行的,所以修改路由規則,使{page}參數是可以選擇性的。將它包含在默認集合中,就可以完成。
通過添加page參數到defaults鍵,{page}占位符已經不再是必須的了。URL地址 /blog 將匹配這條路由規則而且page參數的值被將會被設置成1。 URL地址 /blog/2 也將匹配,賦予page參數值為2。完美!
URL |
route | parameters |
---|---|---|
/blog |
blog | {page} = 1 |
/blog/1 | blog | {page} = 1 |
/blog/2 | blog | {page} = 2 |
當然,你可以使用不止一個可選的占位符(例如 /blog/{slug}/{page}),但是可選擇的占位符后面也必須是可選擇的。例如 /{page}/blog 是一個不合法的路徑,但是頁面將總是必須的。(/blog將不會被這條路由匹配)
后面是可選參數的路由規則將不會匹配結尾是反斜杠的請求。(例如/blog/不會匹配,/blog會匹配)