中間件的主要功能是在達到最終請求動作前對請求進行過濾和處理。
中間件在Laravel中有着廣泛的應用,比如用戶認證、日志、維護模式、開啟Session、從Session中獲取錯誤信息,以及CSRF驗證,等等。
中間件的所在目錄:\app\Http\Middleware。里面有一些默認的middleware
創建自己的middleware
創建middleware非常簡單,我們打開終端,cd到項目目錄下執行以下命令即可:
php artisan make:middleware TestMiddleware
這樣 我們就可以在\app\Http\Middleware下看見我們剛剛創建的middleware了。
<?php namespace App\Http\Middleware; use Closure; class TestMiddleware { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { // 在這里執行我們的邏輯 return $next($request); } }
實現一個簡單的邏輯
我們寫一個小例子來瞧瞧,在TestMiddleware的handle方法中編輯:
public function handle($request, Closure $next) { if ($request->input('age')<18){ return redirect()->route('refuse'); } return $next($request); }
在路由中使用中間件,需要在\app\Http\Kernel.php 文件中進行注冊:
<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application's global HTTP middleware stack. * * @var array */ protected $middleware = [ \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class, \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, \App\Http\Middleware\VerifyCsrfToken::class, ]; /** * The application's route middleware. * * @var array */ protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, // 這是我們注冊的middleware: 'test' => \App\Http\Middleware\TestMiddleware::class, ]; }
注意:我們將testmiddleware注冊到了 $routeMiddleware變量中,laravel的注釋寫的很清楚 如果我們要在全局都使用到這個middleware 就把他注冊到$middleware變量中
接下來我們就可以在路由中使用middleware了:
Route::group(['prefix'=>'laravel', 'middleware'=>'test'], function (){ Route::get('/write', function (){ return 'Write laravel'; }); Route::get('/update', function (){ return 'Update laravel'; }); }); Route::get('/age/refuse',['as'=>'refuse', function(){ return '您的年齡未滿18歲'; }]);
我們在瀏覽器這樣訪問來測試:localhost:8000/laravel/write?age=15 或 localhost:8000/laravel/update?age=20
在請求后執行動作
有些時候,我們需要在請求后執行一些動作,可以這樣寫:
public function handle($request, Closure $next) { $response = $next($request); // 執行一些動作 return $response; }
當然,必要的業務邏輯也有在請求前做認證,在請求后做一些動作的情況。
帶參數的Middleware
除了請求實例$request
和閉包$next
之外,中間件還可以接收額外參數,我們還是以TestMiddleware
為例,現在要求年齡在18歲以上的男性才能訪問指定頁面,handle
方法定義如下:
public function handle($request, Closure $next, $gender) { if ($request->input('age')>=18 && $gender==$request->input('gender')){ return $next($request); } return redirect()->route('refuse'); }
對應的修改路由:
// 使用:語法為middleware傳入參數 Route::group(['prefix'=>'laravel', 'middleware'=>'test:male'], function (){ Route::get('/write', function (){ return 'Write laravel'; }); Route::get('/update', function (){ return 'Update laravel'; }); }); Route::get('/age/refuse',['as'=>'refuse', function(){ return '本站只允許滿18歲的男士訪問'; }]);