[教程] 大白話 Laravel 中間件

Laravel

文章轉(zhuǎn)自:https://learnku.com/laravel/t/27426

Laravel 中間件是什么蛋勺?

簡而言之讥珍,中間件在 laravel 中的作用就是過濾 HTTP 請求,根據(jù)不同的請求來執(zhí)行不同的邏輯操作督赤。

我們可以通過中間件實現(xiàn)以下功能:

  • 指定某些路由
  • 設置 HTTP 響應頭
  • 記錄請求
  • 過濾請求的參數(shù)
  • 決定是否啟用站點維護模式
  • 響應前后做一些必要的操作

自定義中間件

命令行執(zhí)行下面的簡單命令查牌,就可以輕松創(chuàng)建一個新的中間件

php artisan make:middleware <MiddlewareName>
//MiddlewareName 就是你要創(chuàng)建的中間件的名字

執(zhí)行上面的命令蚜点,Laravel 會在 app/Http/Middleware 目錄下自動創(chuàng)建一個只包含 handle 方法的中間件。

<?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);
    }
}

在中間件被調(diào)用的時候先誉,handle 方法就會執(zhí)行湿刽。這里需要注意的是 handle 方法默認有兩個參數(shù) $request$next$request 用來接受應用的請求組求褐耳, $next 將請求傳遞給應用程序诈闺。這兩個參數(shù)是 handle 必不可少的!中間件也包括前置中間件和后置中間件漱病。

“前置中間件” 顧名思義在將請求轉(zhuǎn)發(fā)到應用程序之前處理一些邏輯买雾。 另一方面,在中間件之后杨帽,在應用程序處理了請求并生成響應之后運行漓穿。

前置中間件:

<?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 自帶了大多數(shù)這些中間件例如 ValidatePostSize, TrimStrings,CheckForMaintenanceMode 等等.

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

注冊中間件

創(chuàng)建的任何中間件都必須注冊注盈,因為這是 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 數(shù)組包含全局中間件尉间,它運行應用程序的每個HTTP請求偿乖,所以如果你想為每個請求運行一個中間件,你應該在這里注冊它哲嘲。 $middlewareGroups 使得可以在組中注冊中間件贪薪,從而更容易通過使用組名將大量中間件附加到路由。 $routeMiddleware 數(shù)組包含各個注冊的路由中間件眠副。

分配中間件

有兩個主要方法可以把注冊好的中間件應用到路由中画切。

  • 通過控制器的構(gòu)造方法
  • 通過路由

通過構(gòu)造方法分配中間件

通過構(gòu)造方法分配中間有很大的靈活性,它提供了兩個重要的方法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){

    }

}

使用 exceptonly 方法我們可以選擇把中間件應用到指定方法庞萍。

<?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 中間件組可以像單個中間件一樣分配給路由

中間件參數(shù)

其他參數(shù)可以傳遞給中間件。 典型示例是將每個用戶ID分配給角色钝计,中間件檢查用戶的角色以確定是否有權訪問所請求的 URI恋博。 參數(shù)可以傳遞給中間件,如下所示:

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

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

class ForumController extends Controller
{

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

通過用逗號分隔每個參數(shù)债沮,可以將多個參數(shù)傳遞給中間件。

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

這些參數(shù)在 $next 變量之后傳遞給中間件的 handle 函數(shù)

<?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)
    {   
        //使用解析參數(shù)的中間件邏輯
        return $next($request);
    }
}

總結(jié)

要創(chuàng)建中間件疫衩,請執(zhí)行以下過程

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

Conclusion

Laravel中間件可以更輕松地保護我們的路由,過濾輸入并完成許多其他工作荣德,而無需編寫如此多的邏輯闷煤。 查看官方 Laravel 文檔 這里 了解中間件的更多功能,最重要的是練習涮瞻。

文章轉(zhuǎn)自:https://learnku.com/laravel/t/27426

更多文章:https://learnku.com/laravel/c/translations

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鲤拿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子署咽,更是在濱河造成了極大的恐慌近顷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宁否,死亡現(xiàn)場離奇詭異窒升,居然都是意外死亡,警方通過查閱死者的電腦和手機慕匠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門饱须,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人台谊,你說我怎么就攤上這事冤寿。” “怎么了青伤?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長殴瘦。 經(jīng)常有香客問我狠角,道長,這世上最難降的妖魔是什么蚪腋? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任丰歌,我火速辦了婚禮姨蟋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘立帖。我一直安慰自己眼溶,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布晓勇。 她就那樣靜靜地躺著堂飞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪绑咱。 梳的紋絲不亂的頭發(fā)上绰筛,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音描融,去河邊找鬼铝噩。 笑死,一個胖子當著我的面吹牛窿克,可吹牛的內(nèi)容都是我干的骏庸。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼年叮,長吁一口氣:“原來是場噩夢啊……” “哼具被!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起谋右,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤硬猫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后改执,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啸蜜,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年辈挂,在試婚紗的時候發(fā)現(xiàn)自己被綠了衬横。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡终蒂,死狀恐怖蜂林,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拇泣,我是刑警寧澤噪叙,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站霉翔,受9級特大地震影響睁蕾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一子眶、第九天 我趴在偏房一處隱蔽的房頂上張望瀑凝。 院中可真熱鬧,春花似錦臭杰、人聲如沸粤咪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寥枝。三九已至,卻和暖如春将塑,著一層夾襖步出監(jiān)牢的瞬間脉顿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工点寥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留艾疟,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓敢辩,卻偏偏與公主長得像蔽莱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子戚长,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Laravel 學習交流 QQ 群:375462817 本文檔前言Laravel 文檔寫的很好盗冷,只是新手看起來會有...
    Leonzai閱讀 7,898評論 2 12
  • Laravel框架一:原理機制篇 Laravel作為在國內(nèi)國外都頗為流行的PHP框架,風格優(yōu)雅同廉,其擁有自己的一些特...
    Mr_Z_Heng閱讀 3,689評論 0 13
  • 中間件 簡介 HTTP 中間件為你的應用提供了一種便利的機制去過濾客戶端的請求,比如說laravel中自帶的用來驗...
    Dearmadman閱讀 1,905評論 3 2
  • 什么是中間鍵 對于一個Web應用來說仪糖,在一個請求真正處理前,我們可能會對請求做各種各樣的判斷迫肖,然后才可以讓它繼續(xù)傳...
    伊Summer閱讀 1,666評論 0 3
  • 先說幾句廢話锅劝,調(diào)和氣氛。事情的起由來自客戶需求頻繁變更蟆湖,偉大的師傅決定橫刀立馬的改革使用新的框架(created ...
    wsdadan閱讀 3,053評論 0 12