<?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, $stack], []);
} 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;
}

  

Lavavel5.5源代码 - Pipeline的更多相关文章

  1. Lavavel5.5源代码 - RedisQueue是怎么实现

    队列的基本功能: 1.立即执行:yes 2.延迟执行:yes 3.保证至少执行一次:yes 4.必须执行且最多执行一次:no 用到的数据结构: list.Sorted sets 延迟执行的机制: 1. ...

  2. Lavavel5.5源代码 - 并发数控制

    app('redis')->connection('default')->funnel('key000') // 每个资源最大锁定10秒自动过期,只有60个资源(并发),在3秒内获取不到锁 ...

  3. Lavavel5.5源代码 - 限流工具

    app('redis')->connection('default')->throttle('key000') // 每60秒,只能有10个资源被获取,在3秒内获取不到锁抛出异常 -> ...

  4. jenkins2 pipeline插件的10个最佳实践

    jenkins pipeline的10个最佳实践. 文章来自:http://www.ciandcd.com文中的代码来自可以从github下载: https://github.com/ciandcd ...

  5. jenkins2 pipeline实例

    比较完整的实例,使用了maven打包,git tag,发通知邮件,等待用户deploy,deploy到nexus. 文章来自:http://www.ciandcd.com文中的代码来自可以从githu ...

  6. jenkins2 pipeline入门

    本文通过简单的pipeline的实例和详细的讲解,能够学习基本pipeline的groovy用法,然后开始实现自己的pipeline job. 翻译和修改自:https://github.com/je ...

  7. OpenStack Cinder源代码流程简析

    版权声明:本博客欢迎转载,转载时请以超链接形式标明文章原始出处!谢谢! 博客地址:http://blog.csdn.net/i_chips 一.概况 OpenStack的各个模块都有对应的client ...

  8. 浅谈管道模型(Pipeline)

    本篇和大家谈谈一种通用的设计与处理模型--Pipeline(管道). Pipeline简单介绍 Pipeline模型最早被使用在Unix操作系统中.据称,假设说Unix是计算机文明中最伟大的发明,那么 ...

  9. 【Spark Core】任务运行机制和Task源代码浅析1

    引言 上一小节<TaskScheduler源代码与任务提交原理浅析2>介绍了Driver側将Stage进行划分.依据Executor闲置情况分发任务,终于通过DriverActor向exe ...

随机推荐

  1. alpinelinux

    https://wiki.alpinelinux.org/wiki/Tutorials_and_Howtos https://nixos.org/nix/manual/#ch-installing-b ...

  2. js判断一个对象是否为数组

    1,真正的数组的判断方法 javascript中最简单的声明数组方法为: var a = []; 判断是否为数组的最直接的方法为: 复制代码 代码如下: a instanceof Array //tr ...

  3. vs2015编译纯ASM文件

    x86: 1. 创建一个 C++ 的空项目. 2.解决方案管理器 - 目标项目名 - 右键 - 生成依赖项 - 生成自定义 (VS2015, 如果使用VS2010 你右键就直接能看到生成自定义) 3. ...

  4. Opportunity的chance of success的赋值逻辑

    该字段的值和另外两个字段Sales Stage和Status都相关. 从下列function module CRM_OPPORT_H_PROB_SET_EC可看出,当status不为代码中的这些硬编码 ...

  5. 【[CTSC2018]混合果汁】

    题目 \(CTSC\)也有这么水的题啊 首先看到美味值来自于最小的美味值,我们就可以先考虑把所有的果汁按照美味值排序 接下来可以考虑二分,二分出一个\(mid\)我们只使用美味值大于等于\(mid\) ...

  6. js时间日期格式

    Date.prototype.format = function(format){ var o = { "M+" : this.getMonth()+1, //month &quo ...

  7. 【题解】洛谷P3627 [APIO2009]抢掠计划(缩点+SPFA)

    洛谷P3627:https://www.luogu.org/problemnew/show/P3627 思路 由于有强连通分量 所以我们可以想到先把整个图缩点 缩点完之后再建一次图 把点权改为边权 并 ...

  8. C#基础 一(方法详解)

    需要知道:类和方法的关系 方法和参数修饰符 自定义方法可以有或没有参数,也可以有或没有返回值.可以被各种关键字(static.virtual.public.new等)修饰以限制其行为. C#参数修饰符 ...

  9. Python使用dict和set

    dict Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也成为map,使用键-值(key-value)存储,具有极快的查找速度. 假设要根据同学的名字查找对应的 ...

  10. windows下搭建python

    windows下搭建python 下载python版本  https://www.python.org/   注意当前操作系统的位数,32位还是64位 同时   安装后  修改环境变量         ...