thinkphp中間件是什么意思

thinkphp中間件是什么意思

從5.1.6+版本開始,正式引入中間件的支持。

中間件主要用于攔截或過濾應用的http請求,并進行必要的業務處理。

定義中間件

可以通過命令行指令快速生成中間件

php?think?make:middleware?Check

這個指令會 application/http/middleware目錄下面生成一個Check中間件。

立即學習PHP免費學習筆記(深入)”;

<?php namespace apphttpmiddleware; class Check {     public function handle($request, Closure $next)     {         if ($request->param('name')?==?'think')?{ ????????????return?redirect('index/think'); ????????} ????????return?$next($request); ????} }

中間件的入口執行方法必須是handle方法,而且第一個參數是Request對象,第二個參數是一個閉包

中間件handle方法的返回值必須是一個Response對象。

在這個中間件中我們判斷當前請求的name參數等于think的時候進行重定向處理。否則,請求將進一步傳遞到應用中。要讓請求繼續傳遞到應用程序中,只需使用 $request 作為參數去調用回調函數 $next 。

在某些需求下,可以使用第三個參數傳入額外的參數。

<?php namespace apphttpmiddleware; class Check {     public function handle($request, Closure $next, $name)     {         if ($name == &#39;think&#39;) {             return redirect(&#39;index/think&#39;);         }         return $next($request);     } }

前置/后置中間件

中間件是在請求具體的操作之前還是之后執行,完全取決于中間件的定義本身。

下面是一個前置行為的中間件

<?php namespace apphttpmiddleware; class Before {     public function handle($request, Closure $next)     {         // 添加中間件執行代碼         return $next($request);     } }

下面是一個后置行為的中間件

<?php namespace apphttpmiddleware; class After {     public function handle($request, Closure $next)     { $response = $next($request);         // 添加中間件執行代碼         return $response;     } }

來個比較實際的例子,我們需要判斷當前瀏覽器環境是在微信或支付寶

namespace?apphttpmiddleware; /** ?*?訪問環境檢查,是否是微信或支付寶等 ?*/ class?InAppCheck { ????public?function?handle($request,?Closure?$next) ????{ ????????if?(preg_match('~micromessenger~i',?$request-&gt;header('user-agent')))?{ ????????????$request-&gt;InApp?=?'WeChat'; ????????}?else?if?(preg_match('~alipay~i',?$request-&gt;header('user-agent')))?{ ????????????$request-&gt;InApp?=?'Alipay'; ????????} ????????return?$next($request); ????} }

然后在你的移動版的module里添加一個middleware.php文件

例如:/path/application/mobile/middleware.php

return?[ ????apphttpmiddlewareInAppCheck::class, ];

然后在你的controller中可以通過$this->request->InApp獲取相關的值

注冊中間件

路由中間件

最常用的中間件注冊方式是注冊路由中間件

Route::rule('hello/:name','hello') -&gt;middleware('Auth');

或者使用完整的中間件類名

Route::rule('hello/:name','hello') -&gt;middleware(apphttpmiddlewareAuth::class);

支持注冊多個中間件

Route::rule('hello/:name','hello') -&gt;middleware(['Auth',?'Check']);

V5.1.7+版本,你可以直接在應用配置目錄下的middleware.php中先預定義中間件(其實就是增加別名標識),例如:

return?[ 'auth'=&gt;apphttpmiddlewareAuth::class, ????'check'=&gt;apphttpmiddlewareCheck::class ];

然后直接在路由中使用中間件別名注冊

Route::rule('hello/:name','hello') -&gt;middleware(['auth',?'check']);

V5.1.8+版本開始,可以支持使用別名定義一組中間件,例如:

return?[ 'check'=&gt;[ ????apphttpmiddlewareAuth::class, ???apphttpmiddlewareCheck::class ????], ];

然后,直接使用下面的方式注冊中間件

Route::rule('hello/:name','hello') -&gt;middleware('check');

支持對路由分組注冊中間件

Route::group('hello',?function(){ Route::rule('hello/:name','hello'); })-&gt;middleware('Auth');

V5.1.8+版本開始支持對某個域名注冊中間件

Route::domain('admin',?function(){ //?注冊域名下的路由規則 })-&gt;middleware('Auth');

如果需要傳入額外參數給中間件,可以使用

Route::rule('hello/:name','hello') -&gt;middleware('Auth:admin');

如果使用的是常量方式定義,可以在第二個參數傳入中間件參數。

Route::rule('hello/:name','hello') -&gt;middleware(Auth::class,?'admin');

如果需要定義多個中間件,使用數組方式

Route::rule('hello/:name','hello') -&gt;middleware([Auth::class,?'Check']);

可以統一傳入同一個額外參數

Route::rule('hello/:name','hello') -&gt;middleware([Auth::class,?'Check'],?'admin');

或者單獨指定中間件參數。

Route::rule('hello/:name','hello') -&gt;middleware(['Auth:admin',?'Check:editor']);

使用閉包定義中間件

你不一定要使用中間件類,在某些簡單的場合你可以使用閉包定義中間件,但閉包函數必須返回Response對象實例。

Route::group('hello',?function(){ Route::rule('hello/:name','hello'); })-&gt;middleware(function($request,Closure?$next){ ????if?($request-&gt;param('name')?==?'think')?{ ????????return?redirect('index/think'); ????} ???? return?$next($request); });

全局中間件

你可以在應用目錄下面定義middleware.php文件,使用下面的方式:

<?php return [ apphttpmiddlewareAuth::class,     &#39;Check&#39;,     &#39;Hello&#39;, ];

中間件的注冊應該使用完整的類名,如果沒有指定命名空間則使用apphttpmiddleware作為命名空間。

全局中間件的執行順序就是定義順序。可以在定義全局中間件的時候傳入中間件參數,支持兩種方式傳入。

<?php return [ [apphttpmiddlewareAuth::class, &#39;admin&#39;],     &#39;Check&#39;,     &#39;Hello:thinkphp&#39;, ];

上面的定義表示 給Auth中間件傳入admin參數,給Hello中間件傳入thinkphp參數。

模塊中間件

V5.1.8+版本開始,支持模塊中間件定義,你可以直接在模塊目錄下面增加middleware.php文件,定義方式和應用中間件定義一樣,只是只會在該模塊下面生效。

控制器中間件

V5.1.17+版本開始,支持為控制器定義中間件。首先你的控制器需要繼承系統的thinkController類,然后在控制器中定義middleware屬性,例如:

<?php namespace appindexcontroller; use thinkController; class Index extends Controller {     protected $middleware = [&#39;Auth&#39;];     public function index()     {         return &#39;index&#39;;     }     public function hello()     {         return &#39;hello&#39;;     } }

當執行index控制器的時候就會調用Auth中間件,一樣支持使用完整的命名空間定義。

如果需要設置控制器中間的生效操作,可以如下定義:

<?php namespace appindexcontroller; use thinkController; class Index extends Controller {     protected $middleware = [      &#39;Auth&#39; =>?['except'?=&gt;?['hello']?], ????????'Hello'?=&gt;?['only'?=&gt;?['hello']?], ????]; ????public?function?index() ????{ ????????return?'index'; ????} ????public?function?hello() ????{ ????????return?'hello'; ????} }

中間件向控制器傳參

可以通過給請求對象賦值的方式傳參給控制器(或者其它地方),例如

<?php namespace apphttpmiddleware; class Hello {     public function handle($request, Closure $next)     {         $request->hello?=?'ThinkPHP'; ???????? ????????return?$next($request); ????} }

注意,傳遞的變量名稱不要和param變量有沖突。

然后在控制器的方法里面可以直接使用

public?function?index(Request?$request) { return?$request-&gt;hello;?//?ThinkPHP }

本文來自ThinkPHP框架技術文章欄目:http://www.php.cn/phpkj/thinkphp/

以上就是

? 版權聲明
THE END
喜歡就支持一下吧
點贊10 分享