### 執行流程
上一節大家已經了解了路由的基本概念和簡單用法,本篇就來詳細了解下路由的工作原理和執行流程。
路由的執行過程主要分為三大部分:路由注冊、路由檢查和路由解析,而每個部分又包含很多步驟。
#### 注冊路由
要使用路由功能,必須確保開啟路由功能:
~~~
// 開啟路由功能
'url_route_on' => true,
~~~
> 【5.1須知】
> 不需要配置開啟路由,默認開啟且不能關閉
然后進行路由規則的注冊(或者說定義),路由的注冊包括單個路由、路由分組、路由別名、資源路由、變量規則注冊以及域名路由注冊等等。
對于開發者來說,路由的主要工作就是注冊路由(上面提及的注冊環節我們在后面的內容中都會陸續講解),而路由的匹配和解析一般是由系統自動完成的。
注冊路由的時候會把路由規則注冊到對應的請求類型(包括`GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS`)數組,如果是`any`或者`rule方法`直接注冊的(也包括批量導入的)則會注冊到一個默認的`*請求類型`(代表全部請求類型有效),但同時也會分別在各個請求類型的路由規則里面注冊一個快捷方式(使用true注冊),告訴系統當前請求類型的該路由規則請直接獲取`*`中的路由規則定義。
#### 路由配置
如果在應用配置中關閉了路由功能的話
~~~
// 關閉路由功能
'url_route_on' => false,
~~~
則不會進行路由的注冊和檢測,前面我們提過不要在路由配置文件之外進行路由注冊,因為如果你是在應用的公共函數文件中注冊了路由,即使你關閉路由也仍然會去注冊路由,雖然沒有任何意義。
最關鍵的一點是不在路由配置文件中注冊的路由無法進行路由緩存。
5.0的路由配置是不支持在模塊配置文件中定義的,因為在讀取模塊之前,路由已經檢測完成了。如果你想做的是給不同模塊注冊的路由規則能夠分開不同的文件,便于開發的時候分工協作,那其實是有辦法的,只需要修改應用配置文件中的下面參數:
~~~
// 設置路由配置文件列表
'route_config_file' => ['home','admin'],
~~~
`application/home.php`配置`home模塊`的路由規則,`application/admin.php`則配置`admin模塊`的路由規則。
雖然運行的時候依然會同時加載并注冊,但定義的時候是明確分開了,便于協作。因此路由配置文件不一定是route.php。
> 【5.1須知】
> 直接可以在route目錄下面添加不同模塊的路由定義文件,無需配置
#### 注冊方法
完成路由注冊功能的方法有很多,包括:
|方法名 |描述|
|--|--|
|rule |基本路由注冊|
|any |任意請求路由注冊|
|get |GET請求路由注冊|
|post |POST請求路由注冊|
|put |PUT請求路由注冊|
|patch |PATCH請求路由注冊|
|delete |DELETE請求路由注冊
|alias |別名路由注冊|
|group |路由分組注冊|
|controller |控制器方法路由注冊|
|resource |資源路由注冊|
|pattern |全局路由變量規則注冊|
|import |靜態注冊路由(導入路由配置)|
|domain |域名路由注冊或者域名綁定|
|miss |MISS路由注冊|
|auto |AUTO路由注冊|
這些路由注冊方法中最基本的就是rule方法,其它大部分注冊方法都是調用該方法。
路由注冊其實有一些比較特殊的情況,比如分組路由就是先注冊一個路由分組,然后在分組下面再注冊實際的路由規則,同時這些路由規則可以公用所屬路由分組的參數及變量規則,免得重復定義。關于路由分組和一些特殊路由的用法,我們會在后面單獨講解,暫且不必深究。
路由注冊后,你可以通過下面的方法查看所有的路由規則(包括路由變量、域名和別名等信息):
~~~
// 獲取全部的路由信息
Route::rules();
// 獲取GET路由信息
Route::rules('GET');
~~~
> 【5.1須知】
5.1路由的存儲方式改為對象存儲,所以rules方法作用已經改變
#### 路由緩存
路由注冊是在每次請求的時候完成,然后再進行路由檢查。那么問題來了,為啥每次都要重復注冊路由規則呢,能否把路由規則緩存起來?
答案是當然可以,在開發階段由于會進行路由的調整,當實際部署上線的時候,其實路由規則就不會變化了,那么我們就可以把路由規則緩存起來,以后的每次請求就不需要重復執行路由注冊操作了,能夠提高不少的性能(尤其你的路由規則相當多的情況下)。
緩存路由很簡單,到操作系統的命令行下面,在應用根目錄下面執行命令:
~~~
php think optimize:route
~~~
執行后會在`runtime`目錄下面生成一個`route.php`路由緩存文件,再次請求的時候就會直接讀取緩存文件里面的路由規則。
注冊和讀取路由規則的關鍵代碼在 `think\App`類的`routeCheck`方法,主要代碼如下:
~~~
if (is_file(RUNTIME_PATH . 'route.php')) {
// 讀取路由緩存
$rules = include RUNTIME_PATH . 'route.php';
if (is_array($rules)) {
Route::rules($rules);
}
} else {
$files = $config['route_config_file'];
foreach ($files as $file) {
if (is_file(CONF_PATH . $file . CONF_EXT)) {
// 導入路由配置
$rules = include CONF_PATH . $file . CONF_EXT;
if (is_array($rules)) {
Route::import($rules);
}
}
}
}
~~~
路由緩存只會緩存在路由配置文件(確切的說是`route_config_file`配置的文件列表)中定義的路由規則(包括動態注冊和靜態注冊的規則),所以再次強調,不要在路由配置文件之外注冊路由規則,否則將享受不到路由緩存帶來的性能提升。
> 【5.1須知】
5.1的路由注冊支持延遲注冊,性能大幅提升,因此不需要路由緩存,該指令的作用變化,如果需要使用路由反解的話 可以執行該指令生成緩存。
#### 路由檢查
路由檢查指的是把當前的請求URL地址依次和注冊的路由規則進行變量和條件檢查,如果不匹配則進行下一個路由規則的檢查,直到匹配到正確的路由規則則進入下一步:**路由解析**。如果沒有匹配到任何路由規則,則按照系統默認的規則進行URL解析。
路由檢測的路由規則是當前請求類型的路由規則,其它請求類型的路由就沒必要浪費時間一起檢查了,下面的代碼就是獲取當前請求類型的路由規則。
~~~
$method = $request->method();
// 獲取當前請求類型的路由規則
$rules = self::$rules[$method];
~~~
路由注冊的基本方法如下:
~~~
Route::rule('路由規則','路由地址','請求類型','路由參數(數組)','變量規則(數組)');
~~~
* * * * *
http://www.hmoore.net/thinkphp/route-master/223110