laravel管道模式理解
简化版Pipeline
代码摘自 https://blog.csdn.net/qq_24095941/article/details/84970774
<?php
class Pipeline
{
/**
* The method to call on each pipe
* @var string
*/
protected $method = 'handle';
/**
* The object being passed throw the pipeline
* @var mixed
*/
protected $passable;
/**
* The array of class pipes
* @var array
*/
protected $pipes = [];
/**
* Set the object being sent through the pipeline
*
* @param $passable
* @return $this
*/
public function send($passable)
{
$this->passable = $passable;
return $this;
}
/**
* Set the method to call on the pipes
* @param array $pipes
* @return $this
*/
public function through($pipes)
{
$this->pipes = $pipes;
return $this;
}
/**
* @param \Closure $destination
* @return mixed
*/
public function then(\Closure $destination)
{
$pipeline = array_reduce(array_reverse($this->pipes), $this->getSlice(), $destination);
return $pipeline($this->passable);
}
/**
* Get a Closure that represents a slice of the application onion
* @return \Closure
*/
protected function getSlice()
{
return function($stack, $pipe){
return function ($request) use ($stack, $pipe) {
return $pipe::{$this->method}($request, $stack);
};
};
}
}
解读
表面看起来有点绕,其实简单理解起来就是我们现实中常说的套娃。
等闭包函数执行起来,所send的数据就会被套在闭包中间。这样就实现了所谓的中间件。
简单实例
代码摘自 https://blog.csdn.net/qq_24095941/article/details/84970774
<?php
class ALogic
{
public static function handle($data, $next)
{
print "开始 A 逻辑";
$ret = $next($data);
print "结束 A 逻辑";
return $ret;
}
}
class BLogic
{
public static function handle($data, $next)
{
print "开始 B 逻辑";
$ret = $next($data);
print "结束 B 逻辑";
return $ret;
}
}
class CLogic
{
public static function handle($data, $next)
{
print "开始 C 逻辑";
$ret = $next($data);
print "结束 C 逻辑";
return $ret;
}
}
$pipes = [
ALogic::class,
BLogic::class,
CLogic::class
];
$data = "any things";
(new Pipeline())->send($data)->through($pipes)->then(function($data){ print $data;});
输出结果,换行是人为加上去的。
开始 A 逻辑
开始 B 逻辑
开始 C 逻辑
any things
结束 C 逻辑
结束 B 逻辑
结束 A 逻辑
等价
// 最终会返回一个闭包
return function ($request) use ($stack, $pipe) {
return $pipe::{$this->method}($request, $stack);
};
// 闭包架构会随着array_reduce被整理成以下逻辑(伪代码):
clourse() {
return ALogic->handle({
BLogic->handle({
CLogic->handle({
// 所以可以简单理解为套娃模式
$destination($data);
})
})
});
};
// 反转管道队列是因为要后进先出,这样才能满足预期的结果。
所以管道模式最终的目的是要将过滤器分解成一个个子任务,在子任务中将数据一层层过滤。这也是laravel中间件的实现原理。
laravel管道模式理解
http://blog.icy8.cn/posts/38672/