## 7. 路由分组
>[info] ###提取路由静态部分,以动态变量区分不同路由地址,提高匹配效率。
![](https://box.kancloud.cn/50ca2e1a9e854dbd2e93a0ff4e010ff6_729x267.png)
* * * * *
### 7-1 路由分组的基本概念:
* 我们先看一下典型的路由注册文件:route.php
~~~
<?php
use think\Route; //导入路由类
Route::get(
'staff/:id$', //路由表达式:静态地址/:动态变量
'index/Index/getStaff', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
['id'=>'\d{4}'] //变量规则:\d{4} 必须是数字0-9,且必须是4位
);
Route::get(
'staff/:salaryMin/:salaryMax$', //路由表达式:静态地址/:动态变量
'index/Index/getSalary', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
[
'salaryMin'=>'\d{3,5}', //变量规则:必须是纯数字0-9,且必须在3到5位之间
'salaryMax'=>'\d{3,5}' //变量规则:必须是纯数字0-9,且必须在3到5位之间
]
);
Route::get(
'staff/:ageMin/:ageMax$', //路由表达式:静态地址/:动态变量
'index/Index/getAge', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
[
'ageMin'=>'\d{2}', //变量规则:必须是纯数字0-9,且必须是2位数
'ageMax'=>'\d{2}' //变量规则:必须是纯数字0-9,且必须是2位数
]
);
~~~
> 发现规律了吗?这3个路由规则中,路由表达式的静态地址部分是完全相同的,而动态变量部分各不相同。那我们能不能把相同部分提取出来,来简化我们的路由规则呢?当然可以!
* * * * *
## 准备工作:
>[success] ### 1. 我们先创建一张员工信息表(tp5_staff), 进行查询操作:
1. 根据主键获取指定记录;
2. 根据工资区间,获取相关员工信息;
3. 根据年龄区间,获取相关员工信息;
* 表中信息如下:
![](https://box.kancloud.cn/7599f4a144f919aff051988318a6cb42_694x309.png)
> 数据表的创建与操作请参考课程:http://www.kancloud.cn/ldkt/tp5_db
* * * * *
>[success] ###2. 为了便于演示,我们先创建好控制器:Index.php
~~~
class Index
{
public function getStaff($id)
{
//根据主键查询指定记录(闭包实现)
$data = Staff::get(function ($query) use ($id) {
$query -> field(['id'=>'编号','name'=>'姓名','age'=>'年龄','salary'=>'工资'])
-> where(['id'=>['=',$id]]);
});
//输出该模板对象的原始记录(二维数组)
dump($data->getData());
}
public function getSalary($salaryMin,$salaryMax)
{
//根据工资金额区间,查询符合条件的记录
$data=Staff::all(function($query) use ($salaryMin,$salaryMax) {
$query->field(['id'=>'编号','name'=>'姓名','age'=>'工资'])
-> where(['salary'=>['between',[$salaryMin,$salaryMax]]]);
});
//循环输出该模型对象[数组]的原始记录(二维数组)
foreach ($data as $list) {
dump($list -> getData());
}
}
public function getAge($ageMin,$ageMax)
{
//根据年龄区间,查询符合条件的记录
$data=Staff::all(function($query) use ($ageMin,$ageMax) {
$query->field(['id'=>'编号','name'=>'姓名','age'=>'年龄'])
-> where(['age'=>['between',[$ageMin,$ageMax]]]);
});
//循环输出该模型对象[数组]的原始记录(二维数组)
foreach ($data as $list) {
dump($list -> getData());
}
}
}
~~~
* 控制器代码的简单介绍:
1. `getStaff()` 方法根据数据表主键返回一条记录;
2. `getSalary()`方法根据路由规则给出的salary字段值区间,获取符合条件的数据集合;
3. `getAge()`方法与上面类似,根据URL路由中给出的age字段值区间获取符合条件数据集合;
4. 获取数据,我们全部采用模型类的静态方法实现,查询条件全部采用闭包实现。
>[warning] ###静态方法+闭包查询,是执行效率最高的黄金组合,强烈推荐!
* * * * *
>[success] ### 3.3 创建模型Staff.php
~~~
<?php
namespace app\model;
use think\Model; //导入模型类
class Staff extends Model
{
//此例仅仅是用到了模型的内置方法,此处留空即可
}
~~~
### 7-1: 动态路由分组实例演示
>[info] ### 动态分组路由注册:Route::group( )
#### 第一步:创建路由配置文件:/application/route.php
~~~
<?php
use think\Route; //导入路由类
Route::group('staff', //分组标识符:staff
[
':id$'=>[
'index/Index/getStaff', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
['id'=>'\d{4}'] //变量规则:\d{4} 必须是数字0-9,且必须是4位
],
':salaryMin/:salaryMax$'=>[
'index/Index/getSalary', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
[
'salaryMin'=>'\d{3,5}', //变量规则:必须是纯数字0-9,且必须在3到5位之间
'salaryMax'=>'\d{3,5}' //变量规则:必须是纯数字0-9,且必须在3到5位之间
]
],
':ageMin/:ageMax$'=>[
'index/Index/getAge', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
[
'ageMin'=>'\d{2}', //变量规则:必须是纯数字0-9,且必须是2位数
'ageMax'=>'\d{2}' //变量规则:必须是纯数字0-9,且必须是2位数
]
]
]);
~~~
* * * * *
### 第二步:测试动态路由分组
>[success] ####1. 查询主键等于1016的员工信息
* 浏览器中输入:http://tp5.com/staff/1016.html
> 根据变量规则,参数是4位纯数字,将自动调用:index/Index/getStaff操作,并传入主键1016给参数$id;
* 运行结果:
~~~
array(4) {
["编号"] => int(1016)
["姓名"] => string(6) "马云"
["年龄"] => int(10)
["工资"] => float(3900)
}
~~~
* 生成的SQL语句:
~~~
SELECT `id` AS `编号`,`name` AS `姓名`,`age` AS `年龄`,`salary` AS `工资` FROM `tp5_staff` WHERE `id` = 1016 LIMIT 1;
~~~
>[success] ####2. 查询工资在5000元到6000元之间的员工信息
* 浏览器中输入:http://tp5.com/staff/5000/6000.html
>根据变量规则,参数数量是2个,且每个参数是3位以上5位以下纯数字,将自动定位到:index/Index/getSalary操作,并传入二个值给参数:$salaryMin和$salaryMax;
* 运行结果如下(有3条满足条件):
~~~
array(3) {
["编号"] => int(1008)
["姓名"] => string(6) "林冲"
["工资"] => int(45)
}
array(3) {
["编号"] => int(1006)
["姓名"] => string(6) "杨康"
["工资"] => int(40)
}
array(3) {
["编号"] => int(1011)
["姓名"] => string(6) "宋江"
["工资"] => int(58)
}
~~~
* 对应生成的SQL语句:
~~~
SELECT `id` AS `编号`,`name` AS `姓名`,`age` AS `工资` FROM `tp5_staff` WHERE `salary` BETWEEN 5000 AND 6000;
~~~
>[success] ####3. 查询年龄在30岁到40岁之间的员工信息
* 浏览器中输入:http://tp5.com/staff/30/40.html
>根据变量规则,参数数量是2个,且每个参数是2纯数字,将自动定位到:index/Index/getAge操作,并传入二个值给参数:$ageMin和$ageMax;
* 查询结果如下(有3条符合条件):
~~~
array(3) {
["编号"] => int(1006)
["姓名"] => string(6) "杨康"
["年龄"] => int(40)
}
array(3) {
["编号"] => int(1009)
["姓名"] => string(6) "武松"
["年龄"] => int(35)
}
array(3) {
["编号"] => int(1010)
["姓名"] => string(9) "西门庆"
["年龄"] => int(30)
}
~~~
* 对应的SQL语句:
~~~
SELECT `id` AS `编号`,`name` AS `姓名`,`age` AS `年龄` FROM `tp5_staff` WHERE `age` BETWEEN 30 AND 40;
~~~
### 7-2:静态路由分组
>[info] ### 非常简单,就是以[数组]方式创建的路由分组!
* 修改路由配置文件:/application/route.php
~~~
<?php
//创建静态路由分组
return [
'[staff]'=>[ //路由分组标识符, 注意必须加方括号:[ ]
':id$'=>[
'index/Index/getStaff', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
['id'=>'\d{4}'] //变量规则:\d{4} 必须是数字0-9,且必须是4位
],
':salaryMin/:salaryMax$'=>[
'index/Index/getSalary', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
[
'salaryMin'=>'\d{3,5}', //变量规则:必须是纯数字0-9,且必须在3到5位之间
'salaryMax'=>'\d{3,5}' //变量规则:必须是纯数字0-9,且必须在3到5位之间
]
],
':ageMin/:ageMax$'=>[
'index/Index/getAge', //路由地址:路由到模块/控制器/操作
['ext'=>'html'], //路由参数:URL必须以html结尾
[
'ageMin'=>'\d{2}', //变量规则:必须是纯数字0-9,且必须是2位数
'ageMax'=>'\d{2}' //变量规则:必须是纯数字0-9,且必须是2位数
]
]
]
];
~~~
* 静态路由分组的测试,与动态分组完全一致,此处不再赘述!
* * * * *
## 总结:
>[success] ###路由分组是一项非常实用的技能,尤其适合于多路由,无论是静态还是动态设置,其效率都是一样的,究竟用哪个,视个人喜好,我用动态路由比较多。