laravel中间件 — 面向AOP编程

AOP面向切面编程

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是laravel框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

laravel中间件

介绍与案例来自官方:laravel中间件

laravel中间件提供了一种方便的机制来检查和过滤进入应用程序的 HTTP 请求。例如,Laravel 包含一个中间件,用于验证您的应用程序的用户是否已通过身份验证。如果用户未通过身份验证,中间件会将用户重定向到您的应用程序的登录屏幕。但是,如果用户通过了身份验证,中间件将允许请求进一步进入应用程序。

可以编写额外的中间件来执行除身份验证之外的各种任务。例如,日志中间件可能会记录对您的应用程序的所有传入请求。Laravel框架中包含了几个中间件,包括用于身份验证和 CSRF 保护的中间件。所有这些中间件都位于app/Http/Middleware目录中。
laravel框架自带中间件

创建中间件命令:

php artisan make:middleware EnsureTokenIsValid

此命令将EnsureTokenIsValid在您的app/Http/Middleware目录中放置一个新类。在这个中间件中,如果提供的token输入匹配指定的值,我们将只允许访问路由。否则,我们会将用户重定向回homeURI:

<?php
namespace App\Http\Middleware;
use Closure;

class EnsureTokenIsValid
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->input('token') !== 'my-secret-token') {
        	//令牌不匹配,则返回http重定向
            return redirect('home');
        }
		//匹配通过,继续执行
        return $next($request);
    }
}

业务需求可以在请求之前也可以在请求之后执行,这个取决于 n e x t ( next( next(request)

//写法一,请求前
public function handle($request, Closure $next)
{
    // 此处执行请求前的业务需求
    return $next($request);
}
//写法二,请求前,也可以请求前后都加入需求
public function handle($request, Closure $next)
{
	// 此处执行请求前的业务需求
    $response = $next($request);
    // 此处执行请求后的业务需求
    return $response;
}

理解中间件的实现

下面需要用到闭包

//闭包的2种写法
(function(){echo 1;})();  //最后的()为执行闭包
$a = function(){echo 1;};
$a();  //最后的()为执行闭包

公共代码(用于下方3种实现方式,这里创建了3个中间件类,和一个Controller类):

class middleware1{
    public function handle(Closure $next) //约束必须传入闭包
    {
            echo 'class middleware1 --前<br>';
            $next();
            echo 'class middleware1 --后<br>';
    }
}

class middleware2{
    public function handle(Closure $next) //约束必须传入闭包
    {
            echo 'class middleware2 --前<br>';
            $next();
            echo 'class middleware2 --后<br>';
    }

}

class middleware3{
    public function handle(Closure $next) //约束必须传入闭包
    {
            echo 'class middleware3 --前<br>';
            $next();
            echo 'class middleware3 --后<br>';
    }

}

class Controller{
    public function index(){
        echo 'this is controller<br>';
    }
}

中间件的实现更像一个管道,request通过层层管道,最后再response返回给客户,
官方也是通过Pipeline(管道)类来实现中间件,先看看下图,再感受下下方的实现代码
在这里插入图片描述

原生面向过程实现中间件

面向过程,以闭包方式一层层包裹,码了个思想,码了个寂寞,emmm…无法扩展,根本不能用

(function(){
    echo 'middleware1 --前<br>';
    (function(){
        echo 'middleware2 --前<br>';
        (function(){
            echo 'middleware3 --前<br>';
            (function(){
                (new Controller)->index(); //这里return结果是个闭包,需要最后再加()执行闭包
            })();
            echo 'middleware3 -- 后<br>';
        })();
        echo 'middleware2 -- 后<br>';
    })();
    echo 'middleware1 -- 后<br>';
})();

运行:
在这里插入图片描述

原生面向对象实现中间件

面向对象,类与闭包结合的方式

(new middleware1)->handle(
    (function(){
        (new middleware2)->handle(
            (function(){
                (new middleware3)->handle(
                    (function(){
                        (new Controller)->index(); //这里return结果是个闭包,需要最后再加()执行闭包
                    })
                );
            })
        );
    })
);

输出:
![在这里插入图片描述](https://img-blog.csdnimg.cn/02936c45ea4f4870b4637915e08a7a56.png

array_reduce管道式实现中间件

class pipeline{
	//中间件注册
    private $pipes = [
        'middleware1',
        'middleware2',
        'middleware3',
    ];

	/**
     * Get a Closure that represents a slice of the application onion.
     *
     * @return \Closure
     */
    public function carry(){
        return function ($stack,$pipe){
            return function () use ($stack, $pipe){
                return (new $pipe)->handle($stack);
            };
        };
    }

    public function then(){
    	//核心实现:array_reduce() 将回调函数 callback 迭代地作用到 array 数组中的每一个单元中,从而将数组简化为单一的值。
    	//array_reverse() 接受数组 array 作为输入并返回一个单元为相反顺序的新数组。
    	//call_user_func 第一个参数 callback 是被调用的回调函数,其余参数是回调函数的参数。
        call_user_func(array_reduce(array_reverse($this->pipes), $this->carry(),function (){
            (new Controller())->index();
        }));
    }
}
$p = new pipeline();
$p->then();

输出:
在这里插入图片描述

laravel实现中间件

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值