中間件是什麼?
每一箇中間件是一個定義了handle方法的類或是一個匿名函數,通常全部中間件放在同一個文件夾middleware中,方便管理public function handle($request, Closure $next)
中間件有什麼用web
這些中間件,在根據請求找到匹配的路由以前就開始執行
// 在 \App\Http\Kernel::$middleware中定義,是一個數組,如 $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \App\Http\Middleware\TrustProxies::class, ]; // 在 \Zhiyi\Plus\Http\Kernel::$middleware的值爲 $middleware = [ \Zhiyi\Plus\Http\Middleware\CrossDomain::class, \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \Zhiyi\Plus\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \Zhiyi\Plus\Http\Middleware\TrustProxies::class, ];
是按上下執行,這裏面的中間執行完後,再執行\Illuminate\Foundation\Http\Kernel::dispatchToRouter()
api
框架內置的中間件放在Illuminate\Foundation\Http\Middleware下面,一共有6個數組
這些中間件是在路由匹配以後,與當前匹配路由及控制器有關
在控制器的構造函數中定義閉包
public function __construct(){ $this->middleWare('auth'); $this->middleWare('log',['only'=>['show','detail']]); }
覆蓋getMiddleware()方法app
public function getMiddleware(){ return ['auth','log',['middleware'=>'hello','options'=>['only'=>['index','show']]]]; }
在第二個參數中定義middleware框架
Route::get('/login',[ 'uses'=>'LoginController@index', 'middleware'=>['abc','def'] ])
直接給路由使用middleware()方法函數
Route::get('/login','')->middleware('中間件1','中間件2');//數組也行
在group中定義this
Route::group(['middleware' => ['has-permission:access-dashboard']], function (Router $router) use ($adminRoute) { ... });
爲何全局中間件是一個完整的類名,而路由中間件是鍵名或羣組名
鍵名或羣組名實際上是對應一箇中間件類,它們的對應關係在Kernel中定義,如spa
kernel中 $routeMiddleware 對應 router中 middleware屬性 kernel中 $middlewareGroups 對應 router中 middlewareGroups屬性 $routeMiddleware = [ 別名 => 有handle方法的類名或匿名函數 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \Zhiyi\Plus\Http\Middleware\RedirectIfAuthenticated::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'ability' => \Zhiyi\Plus\Http\Middleware\UserAbility::class, 'sensitive' => \Zhiyi\Plus\Http\Middleware\DisposeSensitive::class, 'operation' => \Zhiyi\Plus\Http\Middleware\SensitiveOperation::class, 'wang' => function(){這是一個閉包} ]; $middlewareGroups = [ 'web' => [ \Zhiyi\Plus\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \Zhiyi\Plus\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, 'api' //能夠是另外一組名,這樣,若是指定的中間件中web,那麼包括上面的和api組中合起來的全部中間件 'wang' // 也能夠是$routeMiddleware中的一個別名(鍵名) ], 'api' => [ 'throttle:120,1',// :前面是中間件名,:後面是參數 'bindings', ], 'admin' => [ 'ability:admin: login,你沒有權限訪問後臺。', ], ];
路由中間件在進入管道以前,會轉爲如下一個由完整類名組成的一維數組code
Array( [0] => Illuminate\Routing\Middleware\ThrottleRequests:120,1 [1] => Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse [2] => Illuminate\Session\Middleware\StartSession [3] => Illuminate\View\Middleware\ShareErrorsFromSession [4] => Zhiyi\Plus\Http\Middleware\VerifyCsrfToken [5] => Illuminate\Routing\Middleware\SubstituteBindings )
中間件的格式
$this->middleWare('api')
$this->middleWare(function($request,$next){})
new Pipeline($this->app))->send($request) ->through($this->middleware) ->then($this->dispatchToRouter())
new Pipeline($this->container))->send($request)->through($middleware)->then( function ($request) use ($route) { return $this->prepareResponse( $request, $route->run() ); } );