[TOC]
# 簡介
一般情況下,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', // 文章列表
'a1/<id:\d+>' => 'site/index',
],
],
...
],
~~~
> 詳細頁面,未優化前訪問路徑為文章[http://www.domain.com/index.php?r=article/detail.html&id=1](http://www.domain.com/index.php?r=article/detail.html&id=1),優化后訪問路徑為:[http://www.domain.com.cn/article/1390.html](http://www.domain.com.cn/article/1390.html)
> 文章列表頁面修改前為:[http://www.domain.com.cn/article/index.html?country\_id=1](http://www.domain.com.cn/article/index.html?country_id=1),優化后訪問路徑變為:[http://dev.welltrend.com.cn/articles/1.html](http://dev.welltrend.com.cn/articles/1.html)
請按照我下面這樣來配置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',
],
~~~
# 在偽靜態中傳遞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,
];
~~~
- 目錄
- 配置
- 簡介
- 別名
- gii
- 配置項
- 模型
- 簡介
- 增刪改查
- AR和model
- 模型事件
- 場景
- query查詢
- 增刪改
- AR查詢器
- 模型關系定義
- AR模型連表查詢
- fields
- where拼接
- 模塊
- 創建模塊
- 控制器
- 表單
- 跳轉
- 響應
- 驗證器
- Action
- 組件
- url
- 分頁
- 驗證碼
- 緩存
- 文件上傳
- 預啟動組件
- 事件
- 自定義組件
- redis
- 日志
- 行為
- cookie和session
- 基礎知識
- 創建一個類
- 配置一個類
- object基類
- component組件類特性
- phpstorm無法更改php等級
- url地址美化
- 過濾器
- 請求處理
- 請求組件
- 響應組件
- header
- 用戶登錄
- 實現IdentityInterface接口
- 登錄
- 自動檢測登錄
- 獲取用戶信息
- 訪問行為追蹤
- phpstorm+postman斷點調試