微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Lavavel5.5源代码 - Pipeline

<?PHP

class Pipeline
{

    protected $passable;
    protected $pipes = [];
    protected $method = ‘handle‘;

    public function send($passable)
    {
        $this->passable = $passable;

        return $this;
    }

    public function through($pipes)
    {
        $this->pipes = is_array($pipes) ? $pipes : func_get_args();

        return $this;
    }

    public function then(\Closure $destination)
    {
        $pipeline = array_reduce(
            array_reverse($this->pipes),$this->carry(),$this->prepareDestination($destination)
        );

        return $pipeline($this->passable);
    }

    protected function prepareDestination(Closure $destination)
    {
        return function ($passable) use ($destination) {
            return $destination($passable);
        };
    }

    protected function carry()
    {
        return function ($stack,$pipe) { // $stack === 下一个目标函数,$pipe == 数组项
            return function ($passable) use ($stack,$pipe) {
                if (is_callable($pipe)) {
                    // If the pipe is an instance of a Closure,we will just call it directly but
                    // otherwise we‘ll resolve the pipes out of the container and call it with
                    // the appropriate method and arguments,returning the results back out.
                    return $pipe($passable,$stack);
                } elseif (!is_object($pipe)) {
//                    list($name,$parameters) = $this->parsePipestring($pipe);
//
//                    // If the pipe is a string we will parse the string and resolve the class out
//                    // of the dependency injection container. We can then build a callable and
//                    // execute the pipe function giving in the parameters that are required.
//                    $pipe = $this->getContainer()->make($name);
//
//                    $parameters = array_merge([$passable,$stack],$parameters);
                    $pipe = new $pipe;
                    $parameters = array_merge([$passable,[]);
                } else {
                    // If the pipe is already an object we‘ll just make a callable and pass it to
                    // the pipe as-is. There is no need to do any extra parsing and formatting
                    // since the object we‘re given was already a fully instantiated object.
                    $parameters = [$passable,$stack];
                }

                return method_exists($pipe,$this->method)
                    ? $pipe->{$this->method}(...$parameters)
                    : $pipe(...$parameters);
            };
        };
    }

}

class FooOneMiddleware
{
    public function handle($request,\Closure $next)
    {
        echo __METHOD__.":".$request.PHP_EOL;
        return $next($request);
    }
}


class FooTwoMiddleware
{
    public function handle($request,\Closure $next)
    {
        echo __METHOD__.":".$request.PHP_EOL;
        return $next($request);
    }
}

/*
    function array_reduce($array,$callback,$initial=null)
    {
        $acc = $initial;
        foreach($array as $a){
            $acc = $callback($acc,$a);
        }
        return $acc;
    }
 */
{
    $middleware = [
        FooOneMiddleware::class,FooTwoMiddleware::class
    ];
    $then = function () {
        return ‘this is output...‘.PHP_EOL;
    };
    $result = (new Pipeline())
        ->send(‘this is input‘)
        ->through($middleware)
        ->then($then);
    echo $result;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐