[路由] -- Yii2 url地址美化與重寫
第一個教程
目的:我只想去掉瀏覽器位址列中的index.php?r=這一塊。
在/config/web.php中 ’components'=>[] 中新增如下程式碼:
1 'urlManager' => [ 2 'enablePrettyUrl' => true, 3 'showScriptName' => false,//隱藏index.php 4 //'enableStrictParsing' => false, 5 'suffix' => '.html',//字尾,如果設定了此項,那麼瀏覽器位址列就必須帶上.html字尾,否則會報404錯誤 6 'rules' => [ 7 //'<controller:\w+>/<action:\w+>'=>'<controller>/<action>', 8 ], 9 ],
如果帶了改了字尾這一下,請記得一定要給瀏覽器位址列的路徑最後面加上.html。
改了以上這些,我發現?r=這塊可以用/代替訪問了,但是想隱藏掉index.php還是不行。
我們還需在index.php同級的目錄下新增.htaccess檔案:
開啟記事本,輸入以下程式碼:
1 2 3 4 5 6 7 8 9 10 |
Options
+FollowSymLinks
IndexIgnore
*/*
RewriteEngine
on
#
if a directory or a file exists, use it directly
RewriteCond
%{REQUEST_FILENAME} !-f
RewriteCond
%{REQUEST_FILENAME} !-d
#
otherwise forward it to index.php
RewriteRule
. index .php
|
然後儲存在與入口檔案index.php同級的目錄下,也就是/web目錄下,檔名自己填.htaccess,檔案型別選擇 所有檔案 (*.*) ,然後儲存即可。
最後測試OK了!
第二個教程
何為美化路由呢?美化嘛,無外乎就是給路由化化妝,讓她好看點。我雖沒化過妝,那好歹也是見過描描眉的。下面我們就來看看如何給你的路由新增新增點“顏色”的。
yii的路由美化工作,全權由urlManager元件負責。預設情況下,該元件並沒有開啟。
我們在配置檔案backend\config\main.php中簡單配置下該元件
'urlManager' => [
'enablePrettyUrl' => false,
'showScriptName' => true,
'enableStrictParsing' => false,
'suffix' => '',
'rules' => [
],
],
按照我們上文的配置,你可能看不到當前路由有什麼變化,我們來做幾個小例子分別講述下要介紹的這幾個引數
enablePrettyUrl:是否開啟美化效果
我們把false改為true前後,分別訪問下左側的“部落格”選單項,前後對比如下:
false:/index.php?r=blog%2Findex
true:/index.php/blog/index
這效果感覺跟開了美顏相機似的。
showScriptName:是否或略指令碼名index.php
就上面的連結而言,大多數情況下我們並不想展示index.php,我們更想要的是/blog/index效果,這個時候showScriptName的作用就顯現出來了
不過該引數還需要我們配置web伺服器如apache和nginx,為了更詳細的說明,我們準備單獨寫篇文章說說。
enableStrictParsing:是否開啟嚴格解析路由
什麼意思呢?假設我們在開啟了路由美化的功能(enablePrettyUrl設定為true),enableStrictParsing設定為false的情況下,我們直接訪問/index.php/blog/index肯定是沒有問題的。但是如果我們直接訪問/index.php?r=blog%2Findex呢?發現頁面展示的效果是/site/index(實際上這裡展示的預設的路由頁面),並非是部落格列表頁面。如果我們把enableStrictParsing引數設定為true你會發現頁面直接丟擲404。因為這貨設定為true之後,會匹配rules選項中設定的至少一個規則,那我們這裡先設定一個路由,不然沒法繼續了。
'rules' => [
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
],
此時重新整理下/index.php/blog/index就正常了。
rules:包含了路由的匹配規則列表
也就是說,如果我們要定製特殊的路由,就需要通過這個屬性進行配置。
rules包含著我們配置的路由規則列表,當解析一個路由或者生成一個路由的時候,匹配規則的順序是從第一條規則開始,知道匹配到第一個滿足的為止。
我們來說一下rules的每一項的規則,以/blogs為例,當然這是一個不存在的路由,你可以訪問下試試會不會丟擲404異常。
我們在rules的第一項新增,現在我們的rules是下面這樣的
'rules' => [
'/blogs' => '/blog/index',
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
],
這其實就是把我們訪問的/blogs路由對映到/blog/index路由上面了,所以我們訪問/blogs才得以被解析並能正常訪問/blog/index頁面。
我們再舉一個例子,如果我們要求訪問/blogs/1可以展示/blog/view?id=1這個介面呢?
實際上/blog/view?id=1需要一個引數是id,我們可以這樣做一個對映
'/blogs/<id:\d+>' => '/blog/view',
可以自行體會一下。
但是,如果我們的專案要求所有的路由都這樣被解析,每一個都這樣寫rules豈不是很龐大很複雜?
rules不只支援正則匹配,我們還可以配置controller和action匹配所有滿足的路由。比如我們在開啟enableStrictParsing為true後,設定的
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
再比如如果我們想要所有的controller/id對映到controller/view介面,我們可以這樣配置
'rules' => [
'/blogs' => '/blog/index',
// '/blogs/<id:\d+>' => '/blog/view',
'<controller:\w+>/<id:\d+>' => '<controller>/view',
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
],
此時我們訪問 /index.php/blog/1 會正常顯示/blog/view?id=1這個介面。
suffix:url字尾
有時候我們想要訪問的頁面都帶上.html字尾,這個時候只需要簡單的配置suffix引數即可
'suffix' => '.html',
如果我們此時在訪問/index.php/blog/index恐怕是不可以的,因為我們已經要求所有的url字尾都要帶上.html才可以被正常解析!即只有訪問 /index.php/blog/index.html 才是可以的。
urlManager的匹配規則我們掌握了,但是!整個網站的連結是要我們手動寫的,難不成你天天修改規則,我還要天天修改連結的寫法嗎?這簡直就是一場“災難”!
舉一個例子,由於網站前期並沒有考慮頁面路由新增.html字尾利於seo搜尋的問題,小張三,哦不小張,名字有點lower,小三吧,哦不還是小張吧。小張整站的連結的寫法都是這樣的
<a href="/site/index">Yii Forum »</a>
<a href="/site/index2">Yii Forum2 »</a>
<a href="/site/index3">Yii Forum3 »</a>
固定死的寫法,這無異於給自己埋了一顆定時炸彈!
有一天老大說了,要求我們網站所有的連結都加字尾.html。no zuo no die!
再來一個小練習考考各位:
一般情況下,我們的後臺列表的資料分頁是藉助yii\data\Pagination生成的,正常情況下其連結是這樣的
/blog/index?page=2
如果我們想要的連結是下面這種形式的,請問如何設計?
// 其中 2是具體分頁的頁面
/blog/index/2.html
這個例子具體典型性,請一定要先思考再繼續看下面答案!
你是不是沒思考,請先思考後動手嘗試幾種方案後再繼續往下閱讀!
來,我們公佈看看這個案例如何解決
列表頁的資料我們是通過gridview進行展示的,但資料的來源,是通過BlogSearch的search方法提供的,我們看下這個search方法,發現最終提供資料的是ActiveDataProvider例項,這個ActiveDataProvider厲害了,它還集成了分頁類yii\data\Pagination。只需要通過ActiveDataProvider的pagination屬性便可以配置分頁類。具體的分頁基礎可以參考這篇文章。
我們的blog表暫時沒那麼多資料,為了分頁效果我們暫時設定pageSize為2,這裡並設定每頁數量的引數為false
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 2,
'pageSizeParam' => false,
],
]);
接下來我們要做的,便是配置urlManager的路由規則,以便生成的連結滿足我們的需求。
在rules中新增一條如下的規則即可
'<controller:\w+>/<action:\w+>/<page:\d+>' => '<controller>/<action>',
完整版的如下:
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'enableStrictParsing' => true,
'suffix' => '.html',
'rules' => [
'<controller:\w+>/<action:\w+>/<page:\d+>' => '<controller>/<action>',
"<controller:\w+>/<action:\w+>"=>"<controller>/<action>",
],
],
Url工具類的使用
URL工具類實際上只的是yii\helpers\BaseUrl類,實際寫所有連結的時候,我們建議通過該類來生成連結,其好處不可言喻。
如果小張所有的連結都像下面這樣寫,反過來想想,他準能幸福的屁顛屁顛的。
use yii\helpers\Url;
<a href="<?= Url::to(['site/index']) ?>">Yii Forum »</a>
<a href="<?= Url::toRoute('site/index') ?>">Yii Forum2 »</a>
<a href="<?= Url::toRoute(['site/index']) ?>">Yii Forum3 »</a>
細心的同學發現了我們這裡其實列舉了三種寫法,其效果都是一樣的。尤其是使用Url::to方法,引數一定要是屬組形式,屬組形式的引數等同於Url::toRoute的效果。
我們的重心就轉移到Url::toRoute方法上面了。該方法會根據你配置的urlManager元件去生成連結,按照我們上文中對urlManager的配置,我們再來列舉兩個簡單的案例
<a href="<?= Url::to(['/blogs']) ?>">Yii Forum4 »</a>
<a href="<?= Url::to(['site/index', 'id' => 1]) ?>">Yii Forum5 »</a>
其生成的連結形式分別是
<a href="/index.php/blogs.html">Yii Forum4 »</a>
<a href="/index.php/site/index/1.html">Yii Forum5 »</a>
關於路由的美化與連結的生成,我們就說這麼多,尤其是連結的生成需要特別注意哦,no zuo no die!