中间件是什么?
每一个中间件是一个定义了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() ); } );