Yii的路由功能

前言

路由规则的原理就是根据请求的参数A ---> 找到要执行的B,项目中生成url刚好是相反的方向 B ---> A 。原理很简单,yii的路由通过正则的方式进行匹配和映射。我们的重点看一下使用

urlManager

urlManager 作为一个url管理者,所有的路由规则 UrlRule 通过它来管理
在匹配路由的时候会根据配置的先后顺序从上到下进行对 UrlRule 进行匹配,匹配到的直接返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[
'components' => [
'urlManager' => [
'enablePrettyUrl' => true,// 开启 url美化
'showScriptName' => false,//隐藏入口文件 index.php
'enableStrictParsing' => false,//true严格按照rules匹配,也就是必须匹配定义的rules才能解释,正常默认是的失效
'suffix' => '.html',// 后缀
// 路由规则
'rules' => [
// ...
],
],
],
]

动态的添加路由规则

添加规则,模块在bootstrap启动的会后有的需要注册自己规则的通过这个添加,如gii、debug模块就用到

1
public function addRules($rules, $append = true)

路由规则 UrlRule

将配置的路由规则进行拆解创建成 UrlRule 对象,用来进行后续的解析和生成url

规则举例

直接映射

1
['index' => 'ding/bunao']

当访问 /index 时实际访问的是 /ding/bunao

左边正则匹配型

1
['test/<id:\d+>' => 'test/bunao']

当访问 /test/10 的时候实际访问的是 /test/bunao?id=10

1
['test/<year:\d{4}>/<category>' => 'test/bunao'],

当访问 /test/1000/ding 的时候实际访问的是 /test/bunao?year=1000&category=ding

1
2
3
4
5
6
7
8
9
['test-<year:\d{4}>' => 'test/bunao'],
```
> 当访问 `/test-1000` 的时候实际访问的是 `/test/bunao?year=1000`
#### 两边匹配
```php
['<ding:(test|comment)>/<id:\d+>/<bunao:(bunao|update|delete)>' => '<ding>/<bunao>']

当访问 /test/100/bunao 的时候实际访问的是 /test/bunao?id=100

通常会写成下面的形式,方便阅读

1
['<controller:(test|comment)>/<id:\d+>/<action:(bunao|update|delete)>' => '<controller>/<action>']

其他实例

1
['<controller:(post|comment)>/<id:\d+>' => '<controller>/view']

当访问 /post/100 的时候实际访问的是 /post/view?id=100

带有默认值的

1
2
3
4
5
6
7
[
[
'pattern' => 'posts/<page:\d+>/<tag>',// 请求部分
'route' => 'post/index',// 解析部分
'defaults' => ['page' => 1, 'tag' => ''],// 默认值
],
]

当请求 /posts 时实际请求的是 /post/index?page=1&tag=''

限制请求方式的

1
['POST post/<id:\d+>' => 'post/create']

表示请求 /post/100 如果要访问到 /post/create?id=100 必须是 POST 请求

1
['POST,PUT post/<id:\d+>' => 'post/create']

表示允许 postpub 方式请求。多个用 , 隔开

域名匹配

一个项目配置了好几个域名,根据域名来控制访问,比如说pc、mobile、api三个用不同的域名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[
'http://<language:\w+>.example.com/posts' => 'post/index',
'http://admin.example.com/login' => 'admin/user/login',
'http://www.example.com/login' => 'site/login',
]
```
> 用不同的域名访问请求
#### 详细配置
UrlRule详细配置
```php
[
'pattern' => 'posts/<page:\d+>/<tag>',// 请求匹配部分
'verb' => ['post', 'get'], //可以请求的方法
'route' => 'post/index',// 解析规则部分
'host' => 'www.bunao.win', //域名,可以多个域名指向同一项目,且可以根据域名的不同来执行不同的解析,一般不填写,也可以把域名和pattern写在一起, 和pattern拼写在一起的时候要带上:// 或 // 来让知道有域名
'mode' => UrlRule::PARSING_ONLY ,// 该路由的模式,如只能解析或只能创建
'defaults' => ['page' => 1, 'tag' => ''],// 默认值,要和pattern中的参数对应上
'name' => '', // 路由规则名称,一般不写,默认是 pattern的值
],

总结

  1. 如果左边有 <> 而右边没有对应的,则 <> 中定义的匹配到的作为 $_GET 的一组值。
  2. 如果右边有和左边对应的(值相等的) <> ,表示左边匹配到的替换到右边就行了
  3. <> 中的 :\xx 定义的是正则匹配的规则,如::\d+ 匹配任意个数字, :\d{4} 只能匹配4位的数值, :(test|comment) 只能匹配 test 或 comment 中的其中一个

action支持驼峰形式请求

增加支持驼峰形式请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
namespace common\components;
use \yii\web\Controller;//使用web
use yii\base\InlineAction;
class zController extends Controller
{
/**
* Author:Steven 原作者
* Desc:重写路由,处理访问控制器支持驼峰命名法
* @param string $id
* @return null|object|InlineAction
*/
public function createAction($id)
{
if ($id === '') {
$id = $this->defaultAction;
}
$actionMap = $this->actions();
if (isset($actionMap[$id])) {
return \Yii::createObject($actionMap[$id], [$id, $this]);
} elseif (preg_match('/^[a-z0-9\\-_]+$/', $id) && strpos($id, '--') === false && trim($id, '-') === $id) {
$methodName = 'action' . str_replace(' ', '', ucwords(implode(' ', explode('-', $id))));
if (method_exists($this, $methodName)) {
$method = new \ReflectionMethod($this, $methodName);
if ($method->isPublic() && $method->getName() === $methodName) {
return new InlineAction($id, $this, $methodName);
}
}
// 驼峰形式,支持第一个字母小写
} else {
$id = ucfirst($id);
$methodName = 'action' . $id;
if (method_exists($this, $methodName)) {
$method = new \ReflectionMethod($this, $methodName);
if ($method->isPublic() && $method->getName() === $methodName) {
return new InlineAction($id, $this, $methodName);
}
}
}
return null;
}
}

需要驼峰的控制器继承此类就行了
参考 Yii2使用驼峰命名的形式访问控制器
官方文档

echo-ding wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!