middleware 原理

middleware 的原理就是「管道」。

管道 (pipe)

管道类似水净化过程中的层层过滤。

middleware 原理

中间件的意思就是说,在接下来的逻辑之前,需要的操作。
例如江河之水我们不能直接喝,在输出净水之前有过滤细菌的机器。
那么我们把输出净水的逻辑,封装成一个匿名函数 $next,然后只需要这样:

$next = function(){
    echo "输出净水";
}
$next2 = function($next){
    echo "过滤细菌";
    $next();
}
执行:
$next2();
输出:
//过滤细菌
//输出净水

现在发现水里有细沙,我们又引入了过滤细沙的机器,需要在目前过滤系统的之前执行。

$next3 = function($next2){
    echo "过滤细沙";
    $next2();
}
执行:
$next3();
输出:
//过滤细沙
//过滤细菌
//输出净水

实例代码

$step1 = function ($next){
    echo "第一步:过滤小石头".PHP_EOL;
    $next();
};

$step2=function ($next){
    echo "第二步:过滤细沙".PHP_EOL;
    $next();
};

$step3 = function ($next){
    echo "第三步:过滤细菌".PHP_EOL;
    $next();
};

$success = function (){
    echo "最后:输出纯净水".PHP_EOL;
};


$callback = function ($next,$step) {
    return function () use ( $next, $step ) {
        return $step($next);
    };
};
$middleWares = [
    $step1,
    $step2,
    $step3
];

$middleWares=array_reverse($middleWares); //将数组元素顺序反转

call_user_func(
    array_reduce($middleWares,$callback,$success)
);
//第一步:过滤小石头 第二步:过滤细沙 第三步:过滤细菌 最后:输出纯净水

array_reduce

array_reduce ( array $array , callable $callback [, mixed $initial = NULL ] ) : mixed
array_reduce() 将回调函数 callback 迭代地作用到 array 数组中的每一个单元中,从而将数组简化为单一的值。

解释挺不容易明白,$array就是中间件数组;$callback 见上面的 $callback 变量,永远返回一个闭包函数;$initial 意思是 init 初始值,也就是最终的目的「输出净水」$success

模拟laravel中间件

interface MiddleWare{
    public static function handle(Closure $next);
}

class StartSession implements MiddleWare{
    public static function handle( Closure $next ) {
        echo '开启 session'.'<br>';
        $next();
        echo '关闭 session'.'<br>';
    }
}
class AddQueuedCookiesToResponse implements MiddleWare{
    public static function handle( Closure $next ) {
        $next();
        echo '添加下一次请求的token'."<br>";
    }
}
class EbcryptCookies implements MiddleWare{
    public static function handle( Closure $next ) {
        echo '对 cookie 加密'.'<br>';
        $next();
        echo '对 cookie 解密'.'<br>';
    }
}


function getSlice(){
    return function ($stack,$pipe){
        return function () use ($stack,$pipe){
            return $pipe::handle($stack);
        };
    };
}
function then() {
    $pipes = [
        'EbcryptCookies',               //加密请求cookie
        'AddQueuedCookiesToResponse',   //添加下一次请求需要的cookie
        'StartSession',                 //开启session
    ];

    $firstSlice=function(){echo '请求向路由器传递,返回相应'.'<br>';};

    $pipes=array_reverse($pipes);

    call_user_func(
        array_reduce($pipes,getSlice(),$firstSlice)
    );
}

then();
    /*
        对 cookie 加密
        开启 session
        请求向路由器传递,返回相应
        关闭 session
        添加下一次请求的token
        对 cookie 解密
    */
本作品采用《CC 协议》,转载必须注明作者和本文链接
welcome come back
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 4

实例代码最后一段有个小错误,应该是:

call_user_func(
    array_reduce($middleWares,$callback,$success )
);

success写错了

3年前 评论
php_yt (楼主) 3年前
jcc123

很直观

3年前 评论
pndx

收藏了,感觉弄懂了这个会很有用

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
94
粉丝
24
喜欢
156
收藏
346
排名:325
访问:2.9 万
私信
所有博文
社区赞助商