## 7. 路由分組
>[info] ###提取路由靜態部分,以動態變量區分不同路由地址,提高匹配效率。

* * * * *
### 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. 根據年齡區間,獲取相關員工信息;
* 表中信息如下:

> 數據表的創建與操作請參考課程:http://www.hmoore.net/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] ###路由分組是一項非常實用的技能,尤其適合于多路由,無論是靜態還是動態設置,其效率都是一樣的,究竟用哪個,視個人喜好,我用動態路由比較多。