一开始对array_reduce方法不太明白,然后换了一种实现发现好理解很多,下面实现的这个 custom_array_reduce函数,就跟 array_reduce方法实现的结果是一样的
$arr = [1, 2, 3];
function custom_array_reduce($arr, callable $callback, $init = null)
{
$ret = $init;
foreach ($arr as $item) {
$ret = $callback($ret, $item);
}
return $ret;
}
$r1 = array_reduce($arr, function ($ret, $item) {
return $ret = $ret + $item;
}, 10);
$r2 = custom_array_reduce($arr, function ($ret, $item) {
return $ret = $ret + $item;
}, 10);
print_r($r1); // 16
echo "<br>";
print_r($r2); // 16
die;
Laravel中实现中间件的方式主要是应用了 array_reduce方法,下面看代码示例,一个简化版的laravel中间件实现原理
<?php
interface Middleware
{
public static function handle($next);
}
class VerifyCSRFToken implements Middleware
{
public static function handle($next)
{
echo "检查token";
echo "<br>";
$next();
}
}
class SetSession implements Middleware
{
public static function handle($next)
{
echo "设置session";
echo "<br>";
$next();
}
}
class OrderSend implements Middleware
{
public static function handle($next)
{
echo "发送订单";
echo "<br>";
$next();
}
}
$arr = [
'VerifyCSRFToken',
'SetSession',
'OrderSend'
];
$ctrlMethod = function () {
echo "最终执行的控制器方法";
};
$r = array_reduce(array_reverse($arr), function ($ret, $item) {
return function () use ($ret, $item) {
return $item::handle($ret);
};
},$ctrlMethod);
$r(); // 输出结果
//检查token
//设置session
//发送订单
//最终执行的控制器方法
按照上面的custom_array_reduce
的代码示例来理解的话,就容易的多了
1.第一次进行循环的时候 $ret = $ctrlMethod
,$item = 'VerifyCSRFToken'
,那么第一次循环的结果就是
$firstLoop = function ($ret, $item) {
return VerifyCSRFToken::handle(function () {
echo "最终执行的控制器方法";
})
}
2.第二次循环的时候 $ret = $firstLoop
$secondLoop = function ($ret, $item) {
return SetSession::hanlde(function ($ret, $item) {
return VerifyCSRFToken::handle(function () {
echo "最终执行的控制器方法";
});
});
}
3.第三次循环的时候 $ret = $secondLoop
$thirdLoop = function ($ret, $item) {
return OrderSend::handle($ret, $item) {
return SetSession::hanlde(function ($ret, $item) {
return VerifyCSRFToken::handle(function () {
echo "最终执行的控制器方法";
});
});
}
}
三次循环之后变成了这种结构,但是大家发现什么问题了没有,我在调用 $thirdLoop的时候,输出顺序是反过来的,
也就是会先 OrderSend::handle(), 然后SetSession::handle() , 然后VerifyCSRFToken::handle(), 所以我们在使用这个中间件方式的时候,要首先对要通过的中间件进行翻转,这也就是为什么传递的第一个数组要先array_reverse翻转一下数组的原因
————————————————
版权声明:本文为CSDN博主「Vencenty」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43889618/article/details/95218015