由淺入深laravel教程 :中間件

中間件是什麼?
每一箇中間件是一個定義了handle方法的類或是一個匿名函數,通常全部中間件放在同一個文件夾middleware中,方便管理
public function handle($request, Closure $next)
中間件有什麼用web

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

這些中間件,在根據請求找到匹配的路由以前就開始執行

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()api

框架內置的中間件放在Illuminate\Foundation\Http\Middleware下面,一共有6個數組

二: 路由中間件

這些中間件是在路由匹配以後,與當前匹配路由及控制器有關

1: 在控制器中定義

在控制器的構造函數中定義閉包

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']]]];
}

2: 在路由中定義

在第二個參數中定義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
)

中間件的格式

  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()
        );
    }
);
相關文章
相關標籤/搜索