php管道的概念,php管道模式手测

一直在用Laravel框架,很喜欢laravel框架的中间件。在请求到结果之前,如果我们想要对路由或请求进行额外的处理,简单的加个Midleware中间件就行了,很简单,很方便是不是。

最近几天看了下它的中间件的实现方式,把自己的心得感悟写下来分享给大家。

了解管道模式

laravel的中间件用的是管道模式,我们先知道管道模式是什么:

所谓管道(Pipeline)设计模式就是将会数据传递到一个任务序列中,管道扮演者流水线的角色,数据在这里被处理然后传递到下一个步骤

管道,顾名思义,就是一个长长的流水管道,只不过加了许多阀门。所以管道模式大致需要三个角色:管道,阀门和载荷(流水)。如下图:

b051526469bf959cadcf69d17a2a542b.png

管道模式UML模型图

开始代码之前,我们必须先了解管道模式的模型图

f35bbabd8095e91710d2a4d887880d1e.png

简单的实现

根据上面的模型图,我们来实现自己所理解的管道模式的代码:

/**

* PipelineBuilder 接口 即管道

* @method pipe 存入多个阀门

* @method process 输出

*/

interface PipelineBuilderInterface

{

public function __construct($payload);

public function pipe(StageBuilderInterface $stage);

public function process();

}

// 具体的管道类

class Pipeline implements PipelineBuilderInterface

{

protected $payload;

protected $pipes = [];

public function __construct($payload)

{

$this->payload = $payload;

}

public function pipe(StageBuilderInterface $stage)

{

$this->pipes[] = $stage;

return $this;

}

public function process()

{

foreach ($this->pipes as $pipe) {

call_user_func([$pipe, 'handle'], $this->payload);

}

}

}

// 阀门接口

interface StageBuilderInterface

{

public function handle($payload);

}

// 具体的阀门类

class StageOneBuilder implements StageBuilderInterface

{

public function handle($payload)

{

echo $payload .' 真是个';

}

}

// 具体的阀门类

class StageTwoBuilder implements StageBuilderInterface

{

public function handle($payload)

{

echo '帅气的男人';

}

}

// 输出:我真是个帅气的男人

$pipeline = new Pipeline('我');

$pipeline->pipe(new StageOneBuilder)

->pipe(new StageTwoBuilder)

->process();

底层源码

先来看看它的底层源码:

return (new Pipeline($this->container))

->send($request)

->through($middleware)

->then(function ($request) use ($route) {

return $this->prepareResponse(

$request, $route->run()

);

});

上面的代码是处理request请求的一部分代码,send()获取待处理的数据,through()获取中间件,then()传递闭包函数。

基本上,使用laravel pipelines你可以将一个实例对象(object)在多个类之间传递,就像流水顺着管道依次流淌一般,最终呢,层层传递,你就得到了从头至尾一系列执行操作的“最终”结果。

模仿laravel pipeline

interface PipelineInterface

{

public function send($traveler);

public function through($stops);

public function via($method);

public function process();

}

interface StageInterface

{

public function handle($payload);

}

class StageOne implements StageInterface

{

public function handle($payload)

{

echo $payload . ' am really an ';

}

}

class StageTwo implements StageInterface

{

public function handle($payload) {

echo 'awesome man';

}

}

class Pipe implements PipelineInterface

{

protected $container;

protected $passable;

protected $pipes = [];

protected $via = 'handle';

public function __construct($container)

{

$this->container = $container;

}

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 via($method)

{

$this->via = $method;

return $this;

}

public function process()

{

foreach ($this->pipes as $pipe) {

// 返回处理后的结果

$this->passable = call_user_func([$pipe, $this->via], $this->passable);

}

}

}

$container = 'a';

$payload = 'wa';

$pipe = new Pipe($container);

// 输出:I am really an awesome man

$pipe->send($payload)->through([(new StageOne), (new StageTwo)])->process();

结语

上面的代码并没有达到laravel中间件的真正执行部分,例子中只是用到了管道模式的一部分。像then()方法中还用了array_reduce和array_reverse函数来处理请求,这一部分有时间会进一步研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值