中間件定義
中間件主要用於攔截或者過濾 http 請求,並進行必要的業務處理。
可以通過 php think make:middleware MyMiddleware
來創建,創建的中間件位置在 application/http/middleware
文件夾下
中間件的結構
<?php
namespace app\http\middleware;
class Check
{
public function handle($request, \Closure $next)
{
if ($request->param('name') === 'think') {
return redirect('/think');
}
return $next($request);
}
}
中間件的入口執行方法必須是 handle 方法,而且第一個參數是 Request 對象,第二個參數是一個閉包,在一些情況下允許有第三個參數
中間件的注冊
中間件的位置在 application/http/middleware
文件夾下,我們可以在路由、應用目錄、模塊目錄和控制器中注冊使用中間件
路由中間件
在路由中直接注冊中間件:
Route::get('hello/:name', 'index/hello')->middleware('Check'); //Check為上面 中間件的結構 中的例子的中間件類名
支持多個中間件:
Route::get('hello/:name', 'index/hello')->middleware(['Check','Auth']);
此外,在應用配置文件目錄(即 config 文件夾)下的 middleware.php 文件中可以設置中間件的別名:
return [
'check' => app\http\middleware\Check::class,
'auth' => app\http\middleware\Auth::class,
];
然后在路由中就可以這樣使用中間件了:
Route::get('hello/:name', 'index/hello')->middleware('check');
Route::get('hello/:name', 'index/hello')->middleware(['check','auth']);
在新版本中,別名還可以定義一組中間件:
return [
'check' => [
app\http\middleware\Check::class,
app\http\middleware\Auth::class,
]
];
這樣可以實現使用一個別名,注冊多個中間件
應用目錄中間件(全局中間件)
在 application 目錄下定義 middleware.php ,為應用目錄下所有的控制器方法注冊中間件:
<?php
return [
\app\http\middleware\Auth::class,
'Check',
];
模塊中間件
在 index 模塊下定義 middleware.php ,為當前模塊下的所有控制器方法注冊中間件:
return [
app\http\middleware\Auth::class,
'Check',
];
控制器中間件
控制器繼承系統的 think\Controller
類,在控制器中定義 protected 屬性的 middleware ,如下,當前控制器方法就會調用相應的中間件:
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
protected $middleware = ['Auth','check'];//可以使用別名或者中間件類名
public function index()
{
return 'index';
}
public function hello()
{
return 'hello';
}
}
同時在控制器中,對中間件配置 except
或者 only
屬性,可以控制中間件是否生效:
<?php
namespace app\index\controller;
use think\Controller;
class Index extends Controller
{
protected $middleware = [
'Auth' => ['except' => ['hello'] ], //在 hello 方法中不生效
'check' => ['only' => ['hello'] ], //只有在 hello 方法中才生效
];
public function index()
{
return 'index';
}
public function hello($name = 'ThinkPHP5')
{
return 'hello' . $name;
}
}
中間件額外傳參
路由中間件
傳參的幾種方式:
Route::get('hello/:name', 'index/hello')->middleware('Check:value');//只能使用中間件類名,無法使用別名
Route::get('hello/:name', 'index/hello')->middleware(Check::class,'value');
Route::get('hello/:name', 'index/hello')->middleware('Check','value');
Route::get('hello/:name', 'index/hello')->middleware('check','value');
Route::get('hello/:name', 'index/hello')->middleware([Check::class, 'auth'], 'value');//兩個中間件傳同樣的參數,可以使用別名或者中間件類名
Route::get('hello/:name', 'index/hello')->middleware(['Check:value1', 'Auth:value2']);//兩個中間件傳不同的參數,不可以使用別名
在 Check 中間件中的 handle 方法中,就可以使用第三個參數來接收額外的參數 value 了。