[教程] 大白話 Laravel 中間件

Laravel

文章轉自: https://learnku.com/laravel/t...

Laravel 中間件是什麼?

簡而言之,中間件在 laravel 中的做用就是過濾 HTTP 請求,根據不一樣的請求來執行不一樣的邏輯操做。php

咱們能夠經過中間件實現如下功能:

  • 指定某些路由
  • 設置 HTTP 響應頭
  • 記錄請求
  • 過濾請求的參數
  • 決定是否啓用站點維護模式
  • 響應先後作一些必要的操做

自定義中間件

命令行執行下面的簡單命令,就能夠輕鬆建立一個新的中間件laravel

php artisan make:middleware <MiddlewareName>
//MiddlewareName 就是你要建立的中間件的名字

執行上面的命令,Laravel 會在 app/Http/Middleware 目錄下自動建立一個只包含 handle 方法的中間件。web

<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request);
    }
}

在中間件被調用的時候,handle 方法就會執行。這裏須要注意的是 handle 方法默認有兩個參數  $request 和 $next 。 $request 用來接受應用的請求組求, $next 將請求傳遞給應用程序。這兩個參數是 handle 必不可少的!中間件也包括前置中間件和後置中間件。api

「前置中間件」 顧名思義在將請求轉發到應用程序以前處理一些邏輯。 另外一方面,在中間件以後,在應用程序處理了請求並生成響應以後運行。數組

前置中間件:app

<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        //你的邏輯就在這裏
        return $next($request);
    }
}

後置中間件:函數

<?php
namespace App\Http\Middleware;
use Closure;
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);
        //你的邏輯就在這裏 例如 重定向到  `/`

        return $response;
    }
}

中間件的類別

  • 全局中間件
  • 路由中間件

全局中間件針對命中應用程序的每一個請求運行。 Laravel 自帶了大多數這些中間件例如 ValidatePostSizeTrimStrings,CheckForMaintenanceMode 等等.this

路由中間件僅在它們所鏈接的路由上運行
例如  redirectIfAuthenticated.spa

註冊中間件

建立的任何中間件都必須註冊,由於這是 Laravel 知道存在的惟一方式。 要註冊中間件,只需打開名爲 kernel.php 的文件,該文件位於 Http 文件夾中,以下所示:命令行

Laravel

This file contains list of all registered middlewares that come with Laravel by default. it contains three major arrays which
此文件包含默認 Laravel 提供的全部已註冊中間件的列表。 它包含三個主要的中間件組 $middleware , $middlewareGroups 和 $routeMiddleware

<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
    /**
     * 應用程序的全局HTTP中間件。
     *
     * 這些中間件在應用程序的每一個請求期間運行。
     *
     * @var array
     */
    protected $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,
    ];
    /**
     * 應用程序的路由中間件組.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            // \Illuminate\Session\Middleware\AuthenticateSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];
    /**
     * 應用程序的路由中間件.
     *
     * 能夠將這些中間件分配給組或單獨使用。
     *
     * @var array
     */
    protected $routeMiddleware = [
        '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' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        //the just created middlware
        'superadmin' => \App\Http\Middleware\RedirectIfSuperAdmin::class, 
    ];
}

 $middleware 數組包含全局中間件,它運行應用程序的每一個HTTP請求,因此若是你想爲每一個請求運行一箇中間件,你應該在這裏註冊它。  $middlewareGroups 使得能夠在組中註冊中間件,從而更容易經過使用組名將大量中間件附加到路由。 $routeMiddleware 數組包含各個註冊的路由中間件。

分配中間件

有兩個主要方法能夠把註冊好的中間件應用到路由中。

  • 經過控制器的構造方法
  • 經過路由

經過構造方法分配中間件

經過構造方法分配中間有很大的靈活性,它提供了兩個重要的方法except($parameters) 和 only($parameters),這兩個方法能夠容許或阻止中間件應用到控制器中的輔助方法。不使用這兩個方法,中間件將使用與控制器的每一個方法。

<?php
use Illuminate\Http\Request;

class ForumController extends Controller
{

    public function __construct(){
      /**in this case the middleware named auth is applied
       to every single function within this controller
       */
        $this->middleware('auth');
    }

    public function viewForum(){

      return view('index');
    }

    public function edit($id){

    }

    public function delete($id){

    }

}

使用 except 和 only 方法咱們能夠選擇把中間件應用到指定方法。

<?php
use Illuminate\Http\Request;

class ForumController extends Controller
{

    public function __construct(){
      /**the authentication middleware here applies to all functions but
       viewForums() and viewForumDetails() and the opposite of this happens
       when you use only()
       */
        $this->middleware('auth')->except(['viewForums', 'viewForumDetails']);
    }

    public function viewForums(){

      return view('index');
    }

    public function edit($id){

    }

    public function delete($id){

    }

    public function viewForumDetails(){

    }
}

經過路由分配中間件

若是註冊的中間件能夠直接附加到路由,以下所示:

<?php
//方法 1
Route::get('admin/profile', function () {
  //action
})->middleware('auth');

/**方法 2
或者像這樣使用徹底限定的類名:
*/
use App\Http\Middleware\CheckAge;

Route::get('admin/profile', function () {
    // action
})->middleware(CheckAge::class);

//方法 3
Route::group(['middleware' => ['web']], function () {
    //action
});

N:B 中間件組能夠像單箇中間件同樣分配給路由

中間件參數

其餘參數能夠傳遞給中間件。 典型示例是將每一個用戶ID分配給角色,中間件檢查用戶的角色以肯定是否有權訪問所請求的 URI。 參數能夠傳遞給中間件,以下所示:

<?php
//方法1 (Through route)
Route::get('admin/profile', function () {
  //action
})->middleware('auth:<role>'); //<role> 這裏應該被用戶想要傳遞的任何參數替換。

//方法2 (Through a controller)
use Illuminate\Http\Request;

class ForumController extends Controller
{

    public function __construct(){
        $this->middleware('auth:<role>');
    }
  }

經過用逗號分隔每一個參數,能夠將多個參數傳遞給中間件。

<?php
Route::get('admin/profile', function () {
  //action
})->middleware('auth:<role>,<age>,<country>'); //<role>, <age>, <country> 這裏應該被用戶想要傳遞的任何參數替換。

這些參數在 $next 變量以後傳遞給中間件的 handle 函數

<?php
class RedirectIfSuperAdmin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next, $role, $age, $country)
    {   
        //使用解析參數的中間件邏輯
        return $next($request);
    }
}

總結

要建立中間件,請執行如下過程

  • 使用 artisan 命令建立中間件 php artisan make:middleware 中間件名.
  • 在app→Http文件夾中的 kernel.php 中註冊中間件
  • 在建立的中間件中編寫邏輯
  • 將中間件分配給路由或控制器

Conclusion

Laravel中間件能夠更輕鬆地保護咱們的路由,過濾輸入並完成許多其餘工做,而無需編寫如此多的邏輯。 查看官方 Laravel 文檔 這裏 瞭解中間件的更多功能,最重要的是練習。

文章轉自: https://learnku.com/laravel/t...

更多文章: https://learnku.com/laravel/c...
相關文章
相關標籤/搜索