php函数array_reduce的理解

官方文档

https://www.php.net/manual/zh/function.array-reduce.php

array_reduce — 用回调函数迭代地将数组简化为单一的值

array_reduce(array $array, callable $callback, mixed $initial = null): mixed

array_reduce() 将回调函数 callback 迭代地作用到 array 数组中的每一个单元中,从而将数组简化为单一的值。


示例代码

<?php
function sum($carry, $item)
{
    $carry += $item;
    return $carry;
}

function product($carry, $item)
{
    $carry *= $item;
    return $carry;
}

$a = array(1, 2, 3, 4, 5);
$x = array();

var_dump(array_reduce($a, "sum")); // int(15)
var_dump(array_reduce($a, "product", 10)); // int(1200), because: 10*1*2*3*4*5
var_dump(array_reduce($x, "sum", "No data to reduce")); // string(17) "No data to reduce"

参考简书:https://www.jianshu.com/p/3c856976813e

class MakeUp {
    public static function handle(Closure $next) {
        echo '化妆打扮', PHP_EOL;
        $next();
    }
}
class Skirt {
    public static function handle(Closure $next) {
        echo '穿上裙子', PHP_EOL;
        $next();
    }
}
$firstSlice = function (){
    echo '我要出去玩了~', PHP_EOL;
};

$arr = [
    'MakeUp',
    'Skirt'
];
function getSlice(){
    return function ($stack, $pipe){
        echo '<pre>', PHP_EOL;
        echo 'stack :';
        var_dump($stack);
        echo '<hr>', PHP_EOL;
        echo 'pipe :';
        var_dump($pipe);
        echo '</pre>', PHP_EOL;
        echo PHP_EOL;
        return function () use ($stack, $pipe){
            return $pipe::handle($stack);
        };
    };
}

$go = array_reduce($arr, getSlice(), $firstSlice);
$go();

提取webman的中间件类

中间件源码

<?php
/**
 * Class Middleware
 */
class Middleware
{
    /**
     * @var array
     */
    protected static $_instances = [];

    /**
     * @param $all_middlewares
     * @param string $method_name
     * @throws BadRequestException
     */
    public static function load($all_middlewares, $method_name = 'process')
    {
        foreach ($all_middlewares as $app_name => $middlewares) {
            foreach ($middlewares as $class_name) {
                if (\method_exists($class_name, $method_name)) {
                    static::$_instances[$app_name][] = [new $class_name(), $method_name];
                } else {
                    // @todo Log
                    //echo "middleware {$class_name}::{$method_name} not exsits\n";
                    throw new BadRequestException("middleware {$class_name}::{$method_name} not exsits\n", 5);
                }
            }
        }
    }

    /**
     * @param $app_name
     * @param bool $with_global_middleware
     * @return array
     */
    public static function getMiddleware($app_name, $with_global_middleware = true)
    {
        $global_middleware = $with_global_middleware && isset(static::$_instances['']) ? static::$_instances[''] : [];
        if ($app_name === '') {
            return \array_reverse($global_middleware);
        }
        $app_middleware = static::$_instances[$app_name] ?? [];
        return \array_reverse(\array_merge($global_middleware, $app_middleware));
    }

    /**
     * @param $app_name
     * @return bool
     */
    public static function hasMiddleware($app_name)
    {
        return isset(static::$_instances[$app_name]);
    }

    /**
     * @param $app
     * @param $call
     * @param null $args
     * @param bool $with_global_middleware
     * @return Closure|mixed
     */
    public static function getCallback($app, $call, $args = null, $with_global_middleware = true)
    {
        $args = $args === null ? null : \array_values($args);
        $middleware = static::getMiddleware($app, $with_global_middleware);
        if ($middleware) {
            $callback = array_reduce($middleware, function ($carry, $pipe) {
                return function ($context) use ($carry, $pipe) {
                    return $pipe($context, $carry);
                };
            }, function ($context) use ($call, $args) {
                try {
                    if ($args === null) {
                        $response = $call($context);
                    } else {
                        $response = $call($context, ...$args);
                    }
                } catch (\Throwable $e) {
                    throw new BadRequestException($e, 401);
                }
                if (\is_scalar($response) || null === $response) {
                    $response = [];
                }
                return $response;
            });
        } else {
            if ($args === null) {
                $callback = $call;
            } else {
                $callback = function ($context) use ($call, $args) {
                    return $call($context, ...$args);
                };
            }
        }
        return $callback;
    }
}

中间件配置

<?php
/**
 * 中间件配置
 */
return [
    '' => [
        //app\middleware\AuthCheck::class,
        //app\middleware\ActionHook::class,
    ],
    'bot' => [
        IYUU\sdk\CoolQ\MiddleWare\DbInsert::class,
        IYUU\sdk\CoolQ\MiddleWare\EventListen::class
    ],
];

使用方法

1、初始化中间件
Middleware::load(include APPLICATION_PATH . '/conf/middleware.php');

2、获取中间件回调链
$callback = Middleware::getCallback('', array($class, $action));

3、调用中间件回调链
$data = $callback($context);

最后修改:2021 年 08 月 12 日 12 : 49 PM
如果觉得我的文章对你有用,请随意赞赏

发表评论