首頁  >  文章  >  php框架  >  Thinkphp5.1詳細講解中間件的用法

Thinkphp5.1詳細講解中間件的用法

WBOY
WBOY轉載
2022-04-24 11:56:104040瀏覽

這篇文章為大家帶來了關於thinkphp的相關知識,其中主要介紹了關於中間件的用法,包括了什麼是前置中間件、後置中間件,還有路由中間件、全域中間件等等相關內容,下面一起來看看,希望對大家有幫助。

Thinkphp5.1詳細講解中間件的用法

推薦學習:《PHP影片教學

一、中間件的作用

中間件主要用於攔截或過濾應用的HTTP請求,並進行必要的業務處理。例如可以使用中間件來檢查使用者的請求資訊裡是否包含一句話木馬。

行為鉤子和中間件的區別:

#中間件:它是對專案請求做處理,在使用者存取我們的專案時,中間件就可以對於這個請求來判斷使用者是否有權限,或判斷使用者是否有非法存取;

行為鉤子:在某一動作開始或結束的時候會觸發的方法,例如使用者註冊成功記錄日誌;

中間件是對使用者請求做處理,而鉤子則是對使用者動作的處理,中間件相當於過濾器,鉤子相當於事件,都是採用AOP思想。

二、定義中間件

首先,可以透過cmd命令列指令快速產生中間件,在專案的根目錄中執行以下cmd命令:

php think make:middleware Check

 這個指令會 application/http/middleware目錄下方產生一個Check中間件,程式碼如下:

<?php

namespace app\http\middleware;

class Check
{
    public function handle($request, \Closure $next)
    {
        if ($request->param('name') == 'index') {
            return redirect('/');//重定向到首页
        }

        return $next($request);//返回的是一个Response对象
    }
}

# 中間件說明:

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

2、中間件handle方法的回傳值必須是一個Response物件;

3、中間件裡可以直接使用Request對象,取得請求參數;

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

public function handle($request, \Closure $next, $name){
    if ($name == 'index') {
        return redirect('/');//重定向到首页
    }

    return $next($request);
}

#1、前置中間件

前置中間件的意思是,在http請求完成之前,先執行中間件的程式碼。

<?php

namespace app\http\middleware;

class Before
{
    public function handle($request, \Closure $next)
    {
        // 先执行中间件代码
        return $next($request);
    }
}

2、後置中間件 

後置中間件的意思是,在http請求完成之後,才開始執行中間件的程式碼。

<?php

namespace app\http\middleware;

class After
{
    public function handle($request, \Closure $next)
    {
		$response = $next($request);
        //后执行中间件代码
        return $response;
    }
}

 三、註冊中間件

#1、路由中間件

顧名思義,就是指定在某個路由下才會去調用這個中間件,即用戶訪問了這個路由鏈接,就會執行這個中間件。

//用户登录的路由
Route::rule(&#39;login&#39;,&#39;index/User/login&#39;)->middleware('Auth');

 或使用完整的中間件類別名稱:

Route::rule('login','index/User/login')->middleware(app\http\middleware\Auth::class);

# 說明:中間件的註冊建議使用完整的類別名稱,如果沒有指定命名空間則預設使用app\http\middleware作為命名空間

同一個路由也支援註冊多個中間件,只需要middleware()裡面用逗號隔開即可:

Route::rule('login','index/User/login')->middleware(['Auth', 'Check']);

Thinkphp5.1.8  版本後,支援對路由分組註冊中間件,如下:

//一个名为user的路由分组
Route::group('user', function(){
	Route::rule('login','index/User/login');
    Route::rule('register','index/User/register');
})->middleware('Auth');

2、全域中間件

意思是說,所有的(全域) http訪問請求,都會自動呼叫這個中間件。

在application目錄下建立middleware.php文件,程式碼如下:

<?php
return [
    //第1个中间件
	\app\http\middleware\Auth::class,
    //第2个中间件(Check中间件没有指定命名空间,所以会默认使用app\http\middleware作为命名空间)
    &#39;Check&#39;,
];

3、模組中間件

Thinkphp5.1.8 版本以上支援模組中間件定義,你可以直接在模組目錄下面增加middleware.php文件,定義方式和全域中間件定義一樣,只是只會在這個模組下面生效。 

4、控制器中間件 

Thinkphp5.1.17 版本以上支援為控制器定義中間件。首先你的控制器需要繼承系統的think\Controller類,然後在控制器中定義middleware屬性,例如:

<?php
namespace app\index\controller;
use think\Controller;

class Index extends Controller{

    protected $middleware = [&#39;Auth&#39;];

    public function index()
    {
        return &#39;index&#39;;
    }
}

5、使用閉包定義中間件

在某些簡單的場合,我們不需要使用中間件類,這時候可以使用閉包定義中間件,但閉包函數必須傳回Response物件實例。 

Route::group(&#39;hello&#39;, function(){
	Route::rule(&#39;login&#39;,&#39;index/User/login&#39;);
})->middleware(function($request,\Closure $next){
    if ($request->param('name') == 'index') {
        return redirect('/');//重定向到首页
    }    
	return $next($request);
});

 四、給中間件傳入參數

1、全域中間件傳參數

#
<?php
return [
	[\app\http\middleware\Auth::class, &#39;张三&#39;],
    &#39;Check:李四&#39;,
];

上面的定义表示给Auth中间件传入参数为张三,给Check中间件传入参数为李四

2、路由中间件传参数

(1)、给Auth中间件传入参数张三

Route::rule(&#39;login&#39;,&#39;index/User/login&#39;)->middleware('Auth:张三');

 也可以这样写:

Route::rule('login','index/User/login')->middleware(Auth::class, '张三');

(2)、给多个中间件传入同一个参数 

Route::rule('login','index/User/login')->middleware([Auth::class, 'Check'], '张三');

(3)、单独指定各个中间件的参数

Route::rule('login','index/user/login')->middleware(['Auth:张三', 'Check:李四']);

五、中间件向控制器传参数

前面讲的给中间件传入特定的参数 (常量),那么中间要如何向控制器传入参数呢?我们可以通过给Request请求对象赋值的方式传参给控制器(或者其它地方),例如:

<?php
namespace app\http\middleware;

class Auth
{
    public function handle($request, \Closure $next)
    {
        //给控制器传参数
        $request->result = '验证成功';       
        return $next($request);
    }
}

需要特别注意:传递的变量名称不要和Request已有的参数变量名有冲突,比如用户登录请求的Request参数里已经有一个username,那么中间件向控制器传参,就不能再用这个username了,否则会改变原来参数的值。

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

public function index(Request $request)
{
	return $request->result;
}

推荐学习:《PHP视频教程

以上是Thinkphp5.1詳細講解中間件的用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除