PHP array_reduce的用法

3 篇文章 0 订阅

一开始对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翻转一下数组的原因

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值