一個網站運營一段時間後,欄目設定很可能發生變化,此時就有可能導致 URL 變化。而 URL 變化的最大問題就是導致以前的串連失效,對使用者體驗非常不好,而且也會影響搜尋引擎對網站的收錄。所以我們必須保證以前的 URL 不失效。
例如以前新聞頁面的網址是 http://msplinks.com.cn/MDFodHRwOi8vbXkuY29tLzEyMzQ1Ni5odG1s,而現在是 http://msplinks.com.cn/MDFodHRwOi8vbXkuY29tL25ld3Mvc3BvcnRzLzEyMzQ1Ni5odG1s。對於這種需求,我們利用 URL 路由可以輕鬆搞定。
先寫兩個規則:
- # 解析和產生新的新聞頁面 URL
- news_page:
- regex: '/news/([a-z]+)/([0-9]+)\.html'
- config:
- category: 1
- news_id: 2
- defaults:
- controller: news
- action: show
- # 解析老的新聞頁面 URL
- news_page_keep_old:
- regex: '/([0-9]+)\.html'
- config:
- news_id: 1
- defaults:
- controller: news
- action: show
複製代碼
上述兩條規則,放在前面的優先順序更高。
當請求的 URL 是 http://msplinks.com.cn/MDFodHRwOi8vbXkuY29tLzEyMzQ1Ni5odG1s 時,前面的規則匹配失敗,而後面的規則匹配成功。因此請求送給了 news 控制器的 show 動作方法處理,並且附帶 news_id 參數。
- function actionShow()
- {
- $news_id = intval($_GET['news_id']);
- $news = News::find($news_id)->get();
-
- ... 顯示新聞內容
- }
複製代碼
這樣就保證了原有 URL 的有效性。
那麼當請求是 http://msplinks.com.cn/MDFodHRwOi8vbXkuY29tL25ld3Mvc3BvcnRzLzEyMzQ1Ni5odG1s 時,前面的規則就匹配成功,此時就不會再匹配後面的規則。而請求還是 actionShow() 來處理。前面的規則多了一個 category 參數,這裡並沒有用上,直接忽略即可。但這個參數是必不可少的,會用於後面的 URL 產生。
現在我們來看看模板中產生 URL 的代碼:
- url('news/show', array(
- 'news_id' => $news->id,
- 'category' => $news->category_name
- ))
複製代碼
可以看到,這裡我們產生 URL 時使用了 category 參數,因此前面的規則會被用於產生 URL。最終我們會得到類似 http://msplinks.com.cn/MDFodHRwOi8vbXkuY29tL25ld3MvY2Fycy8yMzM0My5odG1s 這樣的結果。
現在我們已經完美的解決了問題:既保證了以前 URL 的有效性,又讓訪問者在訪問老頁面後可以通過頁面中的 URL 導航到新格式的 URL 中。
--------------------------------------
URL 隨心變
除了 SEO,URL 路由還可以讓我們隨心所欲的構造 URL 地址。例如 http://msplinks.com.cn/MDFodHRwOi8vcWVlcGhwLmNvbS9jYXNlcy8xOQ== 這個 URL 規則是:
- cases_show:
- pattern: "/cases/:id"
- defaults:
- controller: "cases"
- action: "show"
- config:
- id: "[0-9]+"
複製代碼
我們把規則改為:
- cases_show:
- regex: '/mygod/show\-me\-the\-money/news\-sports\-(\d+)\.html'
- defaults:
- controller: "cases"
- action: "show"
- config:
- id: 1
複製代碼
這時 URL 就變成 http://msplinks.com.cn/MDFodHRwOi8vcWVlcGhwLmNvbS9teWdvZC9zaG93LW1lLXRoZS1tb25leS9uZXdzLXNwb3J0LTE5Lmh0bWw= 了。可以說和以前的 URL 簡直是兩碼事。
而這些修改和變化,完全不需要我們修改應用程式中的代碼和模板代碼,唯一需要改動的就是路有規則表。