6.0中間件分為系統(tǒng)中間件和應(yīng)用中間件,系統(tǒng)中間件為核心框架內(nèi)置的中間件,應(yīng)用中間件是在應(yīng)用里面創(chuàng)建的中間件。
中間件的主要應(yīng)用場(chǎng)景可以包括對(duì)HTTP請(qǐng)求的數(shù)據(jù)過濾、權(quán)限檢測(cè)、請(qǐng)求攔截等行為,使用中間件能夠讓控制器的定義更加簡單,很多額外的非核心業(yè)務(wù)流程的處理都可以交給中間件執(zhí)行。
從中間件的使用范圍來看,可以分為全局中間件、應(yīng)用中間件、控制器中間件和路由中間件。
全局中間件
全局中間件是在app\middleware.php中定義的中間件,默認(rèn)沒有啟用任何中間件,但對(duì)支持的系統(tǒng)中間件做了注釋,你只需要取消注釋就可以使用相應(yīng)的系統(tǒng)中間件,默認(rèn)內(nèi)容如下:
1
2
3
4
5
6
7
8
9
10
|
return [ // 全局請(qǐng)求緩存 // 'think\middleware\CheckRequestCache', // 多語言加載 // 'think\middleware\LoadLangPack', // Session初始化 // 'think\middleware\SessionInit', // 頁面Trace調(diào)試 // 'think\middleware\TraceDebug', ]; |
系統(tǒng)的部分功能交給中間件進(jìn)行統(tǒng)一管理,包括全局請(qǐng)求緩存、多語言的自動(dòng)檢測(cè)和加載、Session初始化和頁面Trace調(diào)試,也就是說,默認(rèn)安裝后的應(yīng)用是不支持Session的,你必須全局開啟Session初始化中間件后Session才能生效。對(duì)于API應(yīng)用來說,本身就不需要Session功能支持。
你可以在全局中間件定義文件中添加你的應(yīng)用中間件,但盡可能確保系統(tǒng)中間件的優(yōu)先執(zhí)行,中間件定義需要使用完整的類名,通過命令行指令可以快速創(chuàng)建一個(gè)應(yīng)用中間件:
1
|
php think make:middleware Test |
會(huì)自動(dòng)生成一個(gè)app\middleware\Test中間件類,內(nèi)容如下:
1
2
3
4
5
6
7
8
9
10
|
<?php namespace app\middleware; class Test { public function handle( $request , \Closure $next ) { } } |
也支持通過指定完整命名空間的方式創(chuàng)建中間件類
1
|
php think make:middleware app\middleware\Hello |
我們添加一個(gè)測(cè)試輸出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?php namespace app\middleware; class Test { public function handle( $request , \Closure $next ) { echo 'Before Middleware<br/>' ; $response = $next ( $request ); echo 'After Middleware<br/>' ; return $response ; } } |
中間件handle方法的返回值必須是一個(gè)Response對(duì)象。
然后在全局中間件定義中添加
1
2
3
|
return [ \app\middleware\Test:: class , ]; |
假設(shè)我們要訪問的控制器方法為
1
2
3
4
5
6
7
8
9
10
11
|
<?php namespace app\controller; class Index { public function hello() { return 'Hello,ThinkPHP!<br/>' ; } } |
訪問該操作方法的輸出為
Before Middleware
Hello,ThinkPHP!
After Middleware
你可以看出中間件的執(zhí)行過程,從執(zhí)行流程上可以分為前置中間件和后置中間件,當(dāng)然,一個(gè)中間件可能同時(shí)有前置和后置行為,上面的Test中間件就是如此。 $next($request)之前的代碼屬于前置中間件范疇,之后的代碼則屬于后置中間件范疇。
應(yīng)用中間件
如果是多應(yīng)用模式的話,應(yīng)用中間件就是在app\應(yīng)用名\middleware.php中定義的中間件,只會(huì)在該應(yīng)用下有效,定義格式和全局中間件一致。
路由中間件
路由中間件則表示僅在路由匹配之后才會(huì)執(zhí)行某個(gè)中間件,在路由定義中使用middleware方法定義,例如:
1
2
|
Route::get( 'hello/:name' , 'index/hello' ) ->middleware(\app\middleware\Hello:: class ); |
可以給路由分組定義中間件
1
2
3
4
|
Route::group( function (){ Route::get( 'hello/:name' , 'index/hello' ); //... })->middleware(\app\middleware\Hello:: class ); |
如果要執(zhí)行多個(gè)中間件,可以使用
1
2
3
4
|
Route::group( function (){ Route::get( 'hello/:name' , 'index/hello' ); //... })->middleware([\app\middleware\Hello:: class ,\app\middleware\Check:: class ]); |
對(duì)于經(jīng)常要使用的中間件,我們可以定義一個(gè)別名,在config\middleware.php配置文件中,設(shè)置
1
2
3
4
|
return [ 'hello' => \app\middleware\Hello:: class , 'check' => \app\middleware\Check:: class , ]; |
路由定義可以改為:
1
2
3
4
|
Route::group( function (){ Route::get( 'hello/:name' , 'index/hello' ); //... })->middleware([ 'hello' , 'check' ]); |
支持給一組中間件定義別名
1
2
3
|
return [ 'test' => [\app\middleware\Hello:: class ,\app\middleware\Check:: class ], ]; |
路由定義可以改為
1
2
3
4
|
Route::group( function (){ Route::get( 'hello/:name' , 'index/hello' ); //... })->middleware( 'test' ); |
中間件支持傳入一個(gè)參數(shù),中間件定義如下
1
2
3
4
5
6
7
8
9
10
11
12
|
<?php namespace app\middleware; class Hello { public function handle( $request , \Closure $next , string $name = '' ) { echo 'Hello' . $name . '<br/>' ; return $next ( $request ); } } |
可以在路由中間件的第二個(gè)參數(shù)傳入name參數(shù)
1
2
|
Route::get( 'hello/:name' , 'index/hello' ) ->middleware( 'hello' , 'middleware' ); |
除了支持參數(shù)外,你可以在中間件的handle方法中使用依賴注入。
控制器中間件
控制器中間件僅當(dāng)訪問某個(gè)控制器的時(shí)候生效
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php namespace app\controller; class Hello { protected $middleware = [ 'hello' , 'check' ]; public function index() { return 'Hello,ThinkPHP!<br/>' ; } } |
由于前面已經(jīng)定義了中間件別名,所以這里直接使用別名定義,否則你必須使用完整的命名空間定義。
默認(rèn)情況下,控制器中定義的中間件訪問控制器的任何操作方法都會(huì)執(zhí)行,有時(shí)候并不希望所有的操作都需要執(zhí)行中間件,有兩種方式來定義控制器中間件的執(zhí)行過濾。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?php namespace app\controller; class Index { protected $middleware = [ 'hello' => [ 'only' => [ 'hello' ]], 'check' => [ 'except' => [ 'hello' ]], ]; public function hello() { return 'Hello,ThinkPHP!<br/>' ; } public function check() { return 'this action require check!<br/>' ; } } |
hello中間件僅在執(zhí)行Index控制器的hello操作的時(shí)候才會(huì)執(zhí)行,而check中間件除了hello方法外,都會(huì)執(zhí)行,具體效果你可以實(shí)際測(cè)試下。
中間件傳參
中間件和控制器之間傳參的方式有很多,一個(gè)簡單的方法是使用Request來進(jìn)行傳參。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<?php namespace app\middleware; class Hello { public function handle( $request , \Closure $next ) { $request ->hello = 'ThinkPHP' ; return $next ( $request ); } } |
中間件向控制器傳參必須在前置中間件完成,后置中間件向控制器的傳參控制器無法接收。
然后在控制器的方法里面可以直接使用
1
2
3
4
|
public function index(Request $request ) { return $request ->hello; // ThinkPHP } |
到此這篇關(guān)于Thinkphp6.0中間件的具體使用的文章就介紹到這了,更多相關(guān)Thinkphp6.0中間件內(nèi)容請(qǐng)搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://blog.csdn.net/maysh2008/article/details/106357578