


一般情況下,Yii應用生成和接受形如`http://www.domain.com/index.php?r=post/view&id=1`的URL。這個URL分成幾個部分:
* 表示主機信息的`http://www.domain.com`
* 表示入口腳本的`index.php`
* 表示路由的`r=post/view`
* 表示普通查詢參數的`id=1`
**隱藏入口文件**
* Nginx位置
~~~
location / {
try_files $uri $uri/ /index.php?$args;
}
~~~
* Apache配置文件(放在入門文件同級目錄)
~~~
RewriteEngine on
# 如果是一個目錄或者文件,就訪問目錄或文件
RewriteCond %{REQUEST_FILENAME} !-d
# 如果文件存在,就直接訪問文件,不進行下面的RewriteRule
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php
~~~
> 另外服務器需要開啟`rewrite`模塊。
**配置UrlManager組件**
打開`@app/config/main.php`中的`components`下面添加以下代碼,如果想在全局生效可以將配置直接寫入`common`模塊下
~~~
'components'=>[
...
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'suffix' => '.html', // 偽后綴
'rules'=>[
'article/<id:\d+>' => 'article/view', // 文章詳情
'articles/<country_id:\d+>' => 'article/index', // 文章列表
],
],
...
],
~~~
**實現偽靜態**
這是通過`urlManager`(URL管理者)這個組件來實現的,你可以先在控制器里var\_dump一下`Yii::$app->urlManager`這個組件,它是Yii的核心組件
框架默認情況下是沒有開啟偽靜態URL的,我們需要修改一下urlManager組件的配置來開啟偽靜態
在配置里增加`urlManager`組件的配置,注意值是一個數組哦!因為我們要控制一些組件屬性的值嘛
至于這個組件都有什么屬性呢,詳細需要參考官方的urlManager組件的對應類的說明[yii\\web\\UrlManager](http://www.yiichina.com/doc/api/2.0/yii-web-urlmanager)
而咱們要實現偽靜態只需要知道幾個屬性:`enablePrettyUrl`、`showScriptName`、`enableStrictParsing`、`rules`這四個屬性!
請按照我下面這樣來配置urlManager組件:
~~~php
'urlManager' => [
'enablePrettyUrl' => true, //開啟偽靜態URL模式
'showScriptName' => false, //生成的網址里不帶入口腳本名稱
'enableStrictParsing' => true, //開啟嚴格偽靜態模式
'rules' => [
//偽靜態規則配置,下面會講解如何填寫
],
],
~~~
好了,估計`?r=test/abc`這樣的URL一旦訪問時就會找不到頁面而報404錯誤了,說明已經成功開啟了偽靜態模式
接下來我們添加一個URL白名單讓它路由到test控制器的abc方法
上面增加urlManager組件的配置后,里面有個rules屬性,值是一個數組,這里就是放URL白名單的地方了
比如我們要實現`/uiui.html`這個網址訪問到test控制器的abc方法,就這樣添加rules內容:
~~~php
'rules' => [
'uiui.html' => 'test/abc',
],
~~~
神奇的事發生了!當你在瀏覽器輸入“\*\**[http://xxx.com/uiui.html](http://xxx.com/uiui.html)*” 就會運行test控制器abc方法的代碼
然后你試著在控制器里`echo Url::to(['test/abc']);`也會輸出“**/uiui.html**” 這個結果!
再來,你在rules里面將規則改成`'baba.html' => 'test/abc'`那Url::to方法也會將“**test/abc**”這個控制器方法標記生成為“**/baba.html**”
這就是為什么不提倡直接將網址寫死在模板上的原因了,因為偽靜態規則可能會在配置里被改變的,我們應該盡可能用Url::to來生成網址,減少維護的修改量
**在偽靜態中傳遞GET參數**
我們用`/uiui.html`這樣的偽靜態來取代了`/?r=test/abc`的網址形式
那么又如何表達`/?r=test/abc&userId=123`呢?難道是`/uiui123.html`這樣嗎?不行不行
其實簡單地做,就可以這樣寫:`/uiui.html?userId=123`,這樣控制器里依然可以收到參數,不信你試試`Yii::$app->request->get('userId')`
但一般情況下我們項目中都盡量把GET參數也隱藏在偽靜態之中,比如實現
`/uiui7788.html`就相當于`/?r=test/abc&userId=7788`的效果,配置辦法如下:
~~~php
'rules' => [
'uiui<userId:\d+>.html' => 'test/abc',
],
~~~
然后你試試
~~~php
echo Url::to(['test/abc', 'userId' => 7788]);
~~~
就能看到輸出`/uiui7788.html`了
**rules的key寫法簡介**
這里需要一些正則表達式的知識基礎,反正里面就是增加`<`和`>`這兩個符號,表達這塊區域要套一個參數進來
然后以參數的名稱加`:`號開頭,比如`userId:`這樣Url::to方法的`'userId' => 值`才能知道它要生成到偽靜態的哪個位置上
而`:`號后面的`\d+`表示當user\_id的值是數字的時候才可以生成,否則的話,比如`'userId' => 'abc'`這樣的參數放在to方法里
由于值是字符串abc而不是一個數字,所以無法跟rules里的`\d+`(數字)匹配,不會生成預想中的`/uiuiabc.html`,如果要實現這樣的話,必須將`\d+`改成`\w+`(英數字下劃線),如果不熟悉正則基礎的去惡補知識吧
而通常情況下rules配置中我也最常用的就是`\d+`和`\w+`這兩個正則匹配符
**復雜點的多參數偽靜態**
多個參數時其實也很容易理解,看看:
`'uiui<userId:\d+><userName:\w+>-balabala<age:\d{2}><type:\d><width:\d+>-<height:\d+>.html' => 'test/abc'`
這里一共有6個參數,userId、userName、age、type、width和height,其中age只匹配2位數字,type只匹配一位數字
~~~php
echo Url::to(['test/abc',
'userId' => 65535,
'userName' => 'jay',
'age' => 18,
'type' => 4,
'width' => 200,
'height' => 100,
]);
~~~
結果就生成了“**[http://xxx.com/uiui65535jay-balabala184200-100.html](http://xxx.com/uiui65535jay-balabala184200-100.html)**”
對了你有沒有發現,test控制器不用建立abc方法也能生成?其實生成URL只是檢查rules配置,匹配了就生成,它不管你有沒有控制器方法(學過其它框架的話也很清楚,這個不新鮮了)
這個URL代入get參數后就是
~~~php
$_GET = [
'userId' => 45678,
'userName' => 'kkqbx',
'age' => 18,
'type' => 2,
'width' => 1024,
'height' => 768,
];
~~~
**rules的規則定義順序**
相似的幾個偽靜態共存時,精確的偽靜態必須放在最前面,模糊的放后面,比如有以下偽靜態
~~~php
'rules' => [
'a<id:\w+>.html' => 'test/a',
'abc.html' => 'test/b',
]
~~~
當訪問`/abc.html`時永遠不會路由到`test/b`,因為它已經被`a<id:\w+>.html`這條規則匹配成功,不再往下匹配了
想匹配test/b的話就要將`abc.html`這條規則移到test/a的規則前面才可以
重要知識點:**原則上就是越精確的偽靜態就越靠前就好**
比如`abc.html`是沒有正則表達式的,所以它絕對精確地描述了匹配內容,如果將帶正則的規則放在前面就會被別人匹配掉了(因為正則匹配其實就是一種模糊匹配)
- 目錄
- 配置
- 簡介
- 別名
- gii
- 配置項
- 模型
- 簡介
- 增刪改查
- AR和model
- 模型事件
- 場景
- query查詢
- 增刪改
- AR查詢器
- 模型關系定義
- AR模型連表查詢
- fields
- where拼接
- 模塊
- 創建模塊
- 控制器
- 表單
- 跳轉
- 響應
- 驗證器
- Action
- 組件
- url
- 分頁
- 驗證碼
- 緩存
- 文件上傳
- 預啟動組件
- 事件
- 自定義組件
- redis
- 日志
- 行為
- cookie和session
- 基礎知識
- 創建一個類
- 配置一個類
- object基類
- component組件類特性
- phpstorm無法更改php等級
- url地址美化
- 過濾器
- 請求處理
- 請求組件
- 響應組件
- header
- 用戶登錄
- 實現IdentityInterface接口
- 登錄
- 自動檢測登錄
- 獲取用戶信息
- 訪問行為追蹤
- phpstorm+postman斷點調試