由浅入深laravel教程 :中间件

中间件是什么?
每个中间件是一个定义了handle方法的类或是一个匿名函数,一般所有中间件放在同一个文件夹middleware中,方便管理
public function handle($request, Closure $next)
中间件有什么用

一: 路由前中间件(也叫全局中间件)

这些中间件,在根据请求找到匹配的路由之前就开始执行

1.配置

// 在 \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,
];

2.执行顺序

是按上下执行,这里面的中间执行完后,再执行\Illuminate\Foundation\Http\Kernel::dispatchToRouter()

框架内置的中间件放在Illuminate\Foundation\Http\Middleware下面,一共有6个

二: 路由中间件

这些中间件是在路由匹配之后,与当前匹配路由及控制器有关

1: 在控制器中定义

在控制器的构造函数中定义

public function __construct(){
    $this->middleWare('auth');
    $this->middleWare('log',['only'=>['show','detail']]);
}

覆盖getMiddleware()方法

public function getMiddleware(){
    return ['auth','log',['middleware'=>'hello','options'=>['only'=>['index','show']]]];
}

2: 在路由中定义

在第二个参数中定义middleware

Route::get('/login',[
  'uses'=>'LoginController@index',
  'middleware'=>['abc','def']
])

直接给路由使用middleware()方法

Route::get('/login','')->middleware('中间件1','中间件2');//数组也行

在group中定义

Route::group(['middleware' => ['has-permission:access-dashboard']], function (Router $router) use ($adminRoute) {
  ...
});

为什么全局中间件是一个完整的类名,而路由中间件是键名或群组名
键名或群组名其实是对应一个中间件类,它们的对应关系在Kernel中定义,如

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,你没有权限访问后台。',
    ],
];

路由中间件在进入管道之前,会转为以下一个由完整类名组成的一维数组

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
)

中间件的格式

  1. 别名
    $this->middleWare(‘auth’);
  2. 组名

$this->middleWare(‘api’)

  1. 闭包

$this->middleWare(function($request,$next){})

  1. 完整类名 $this->middleWare(IlluminateRoutingMiddlewareThrottleRequests)

三: 使用场景

全局中间件

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()
        );
    }
);
    原文作者:advance100
    原文地址: https://segmentfault.com/a/1190000012146615
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞