![](https://box.kancloud.cn/c30c32377ecaf76611c1f31be8b28c01_602x733.png)
![](https://box.kancloud.cn/e38b826959f77d0062a339f01a805ac7_440x98.png)
![](https://box.kancloud.cn/c8f9fcb6574897cf200351c26550339c_714x330.png)
一般情况下,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断点调试