路由在框架中的作用打個比方的話,路由好比是WEB應用的總調度室,對於訪問的URL地址,路由可以拒絕或者接受某個URL請求,並進行分發調度,而且還有一個副作用是因為路由規則可以隨意定義,因此可以讓你的URL請求地址更優雅,因為不會暴露實際的URL地址,也就意味着更安全,5.0的路由不僅僅只是支持路由到控制器的操作方法,甚至可以路由到任何的類或者閉包。
1、路由模式
路由可以理解為一種尋徑功能模塊,比如URL地址里面的index模塊怎么才能省略呢,默認的URL地址顯得有點長,下面就來說說如何通過路由簡化URL訪問。ThinkPHP5.0的路由比較靈活,並且不需要強制定義,可以總結歸納為如下三種方式:
1.1、普通模式
關閉路由,完全使用默認的PATH_INFO方式URL:
'url_route_on' => false,
路由關閉后,不會解析任何路由規則,采用默認的PATH_INFO 模式訪問URL:
http://serverName/index.php/module/controller/action/param/value/...
但仍然可以通過操作方法的參數綁定、空控制器和空操作等特性實現URL地址的簡化。
可以設置url_param_type配置參數來改變pathinfo模式下面的參數獲取方式,默認是按名稱成對解析,支持按照順序解析變量,只需要更改為:
// 按照順序解析變量 'url_param_type' => 1,
1.2、混合模式
開啟路由,並使用路由定義+默認PATH_INFO方式的混合:
'url_route_on' => true, 'url_route_must'=> false,
該方式下面,只需要對需要定義路由規則的訪問地址定義路由規則,其它的仍然按照第一種普通模式的PATH_INFO模式訪問URL。
1.3、強制模式
開啟路由,並設置必須定義路由才能訪問:
'url_route_on' => true, 'url_route_must' => true,
這種方式下面必須嚴格給每一個訪問地址定義路由規則(包括首頁),否則將拋出異常。
首頁的路由規則采用/定義即可,例如下面把網站首頁路由輸出Hello,world!
Route::get('/',function(){
return 'Hello,world!';
});
2、路由配置
2.1、URL請求的執行流程:用戶請求 -> 路由解析 -> 調度請求 -> 執行操作 -> 響應輸出
2.2、路由規則寫在哪里:
* 路由規則寫在與應用配置統計的route.php文件中
* 路由規則主要使用路由類Route::rule()方法注冊
2.3、設置路由配置文件列表:
'route_config_file' => ['home','admin'],
application/home.php配置home模塊的路由規則,application/admin.php則配置admin模塊的路由規則。
雖然運行的時候依然會同時加載並注冊,但定義的時候是明確分開了,便於協作。
3、路由注冊
路由注冊可以采用方法動態單個和批量注冊,也可以直接定義路由定義文件的方式進行集中注冊。
3.1、動態注冊和靜態路由
現在給該URL地址定義一個新的路由規則如下:
Route::rule('hello/:name','index/Index/hello');
現在我們來分析下rule方法的參數,第一個參數稱為路由規則(通過路由訪問的地址),第二個參數為該規則對應的路由地址(也就是原來定義路由之前訪問的URL地址)。
路由規則通常可以包含變量(例如其中的:name就是一個路由變量),路由規則中包含變量(包括可選變量)的就稱該條路由規則為動態路由,沒有包含任何變量的路由我們稱之為靜態路由,例如:
// 靜態路由規則 Route::rule('hello','index/Index/hello'); // 動態路由規則 Route::rule('hello/:name','index/Index/hello');
注:ThinkPHP5.0的路由規則定義是從根目錄開始,而不是基於模塊名的。並且原來的訪問地址會自動失效。
3.2、URL請求類型
我們知道一個URL請求類型有很多,常用的包括GET/ POST/ PUT/ DELETE等,我們使用rule方法注冊的路由,默認是支持任意請求類型訪問的,不過你可以通過第三個參數來限定請求類型:
Route::rule('hello/:name','index/index/hello','GET');
注:只有通過GET請求的訪問,該路由才會生效。不指定的話默認為任何請求類型
如果你希望路由可以支持所有的請求類型,也可以使用:
Route::any('hello/:name','index/index/hello');
注:any方法其實和rule方法是一樣的,區別在於不用寫第三個參數。
系統提供了為不同的請求類型定義路由規則的簡化方法,例如:
Route::get('new/:id','News/read'); // 定義GET請求路由規則
Route::post('new/:id','News/update'); // 定義POST請求路由規則
Route::put('new/:id','News/update'); // 定義PUT請求路由規則
Route::delete('new/:id','News/delete'); // 定義DELETE請求路由規則
Route::any('new/:id','News/read'); // 所有請求都支持的路由規則
我們也可以批量注冊路由規則,例如:
Route::rule(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']); Route::get(['new/:id'=>'News/read','blog/:name'=>'Blog/detail']); Route::post(['new/:id'=>'News/update','blog/:name'=>'Blog/detail']);
4、路由表達式
路由表達式統一使字符串定義,采用規則定義的方式。
4.1、規則表達式
規則表達式通常包含靜態地址和動態地址,或者兩種地址的結合,例如下面都屬於有效的規則表達式:
'/' => 'index', // 首頁訪問路由 'my' => 'Member/myinfo', // 靜態地址路由 'blog/:id' => 'Blog/read', // 靜態地址和動態地址結合 'new/:year/:month/:day'=>'News/read', // 靜態地址和動態地址結合 ':user/:blog_id'=>'Blog/read',// 全動態地址
每個參數中以“:”開頭的參數都表示動態變量,並且會自動綁定到操作方法的對應參數。
4.2、路由變量
支持對路由參數的可選定義,例如:
'blog/:year/[:month]'=>'Blog/archive',
[:month]變量用[ ]包含起來后就表示該變量是路由匹配的可選變量。
4.3、變量解析方式
路由規則之外的變量解析方式一般是key1/value1/key2/value2解析為key1=value1,key2=value2,也就是說
http://tp5.com/hello/thinkphp/city/shanghai
除了會解析路由變量name之外,還會解析另外一個city變量,分別是:
'name' => 'thinkphp', 'city' => 'shanghai'
當然我們可以設置按順序解析:
'url_param_type' => 1
這個時候如果訪問http://tp5.com/hello/thinkphp/city/shanghai,得到的變量結果就完全不同了:
'name' => 'thinkphp', 0 => 'city', 1 => 'shanghai',
4.4、定制分隔符
我們在定義路由規則的時候,都是統一使用/作為URL分隔符,但並不是表示URL訪問的時候只能使用/作為分隔符,例如我們可以設置參數:
'pathinfo_depr' => '-',
那么URL訪問地址就會變成
http://tp5.com/hello-thinkphp http://tp5.com/hello-thinkphp-beijing
如果你希望某個路由地址使用不同的URL分隔符,有兩種方法:
方法一:param_depr
先介紹第一種比較簡單的,定義路由規則的時候,添加param_depr參數(要求V5.0.2+),例如:
Route::get('hello/:name/[:city]','index/index/hello',['param_depr' => '-'],[ 'name' => '\w+' , 'city' => '[A-Za-z]+' ]);
表示只有在該路由規則訪問的時候,才使用-作為url分隔符。
方法二:組合變量
在一些復雜的路由規則定義中,我們可以使用組合變量定義方式,組合變量的優勢是變量分隔符可以隨意定義,例如:
//正確路徑:http://www.mtp5.com/test/1;注:‘?《name?》’表示可選的,['index/index2/test', []]里面的‘[]’是必須的 'test/<id?>-?<name?>' =>['index/index2/test', []] //正確路徑:http://www.mtp5.com/test-1 'test-<id>-?<name?>' =>['index/index2/test', []] //正確路徑:http://www.mtp5.com/test-1- 'test-<id>-<name?>' =>['index/index2/test', []] //正確路徑:http://www.mtp5.com/test/1- 'test/<id>-<name?>' =>['index/index2/test', []] //正確路徑:http://www.mtp5.com/test1 'test?<id?>-?<name?>' =>['index/index2/test', []] //正確路徑:http://www.mtp5.com/test 'test-?<id?>-?<name?>' =>['index/index2/test', []]
錯誤的寫法:
//錯誤寫法 'test/?<id?>-?<name?>' =>['index/index2/test', []] 'test/[:id]-?<name?>' =>['index/index2/test', []]
注:<name?>表示可選變量,'?<name?>'表示前面的分隔符和這個變量都是可選的
通過本篇內容的學習,你已經掌握了路由變量的使用,下面是路由變量的對比
| 變量定義 | 必須變量 | 可選變量 | 變量分隔符 |
|---|---|---|---|
| 普通變量 | :name |
[:name] |
/ |
| 組合變量 | <name> |
<name?> |
實際URL分隔符 |
4.5、完整匹配
規則匹配檢測的時候只是對URL從頭開始匹配,只要URL地址包含了定義的路由規則就會匹配成功,如果希望完全匹配,可以在路由表達式最后使用$符號,例如:
//正確的寫法
'new/:cate$'=> 'News/category',//路徑:http://serverName/index.php/new/info'hello/[:name]$' => 'index/hello',
//錯誤的寫法
'url/[:id]/[:name$]' => 'index/index2/url',
