ThinkPHP5——route(路由)的詳解


  路由在框架中的作用打個比方的話,路由好比是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.1URL請求的執行流程:用戶請求 -> 路由解析 -> 調度請求 -> 執行操作 -> 響應輸出

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請求類型有很多,常用的包括GETPOSTPUTDELETE等,我們使用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',

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM