介绍
就像其名称管道一样,我们可以把它想象成工厂的生产线。
生产线上的每一个环节就是一个管道,而每一个商品就是管道中传递的值。
按照环节顺序对商品进行检测,当有一个环节检测不达标,则后续环节不会执行。
不达标的商品可能会放到一个回收环节,进行后续处理。
而在laravel中,中间件就扮演着管道中的一个个节点,对管道中的资源(HTTP请求)进行检测,来决定是否放行。
laravel pipeline类的接口定义:
<?php
namespace Illuminate\Contracts\Pipeline;
use Closure;
interface Pipeline
{
/**
* 设置管道中的资源,也就是要经过中间件检测的资源,在框架中传递的是Request对象
*
* @param mixed $traveler
* @return $this
*/
public function send($traveler);
/**
* 设置管道中的一个个节点,也就是一个个类,要经过的中间件列表
*
* @param dynamic|array $stops
* @return $this
*/
public function through($stops);
/**
* 设置执行节点中的哪个方法,默认是handle
*
* @param string $method
* @return $this
*/
public function via($method);
/**
* 上面的方法都是初始化,到这个then这里才是真正开始执行,原理主要使用了array_reduce、array_reverse函数。
*
* @param \Closure $destination
* @return mixed
*/
public function then(Closure $destination);
}
then函数的细节以后再深入理解,这里推荐一篇对原理剖析的不错的文章:https://www.cnblogs.com/guiyishanren/p/11150015.html
使用示例
比如有这样一个场景,有一个物品,需要通过一些检测并对其标记检测结果。(但用的最多的还是中间件,其他场景基本没用过)
$item = [
'weight' => [
'format' => 50,
'verify' => null
],
'width' => [
'format' => 100,
'verify' => null
],
'height' => [
'format' => 200,
'verify' => null
]
];
$pipes = [
\App\Libs\BaseStandard\TestWeight::class,
\App\Libs\BaseStandard\TestWidth::clas,
\App\Libs\BaseStandard\TestHeight::class
];
$verify_result = app(Pipeline::class)
->send($item)
->through($pipes)
->via('check')
->then(function ($item) {
return $item;
});
输出:
array:3 [▼
"weight" => array:2 [▼
"format" => 50
"verify" => "success"
]
"width" => array:2 [▼
"format" => 100
"verify" => "success"
]
"height" => array:2 [▼
"format" => 200
"verify" => "success"
]
]
\App\Libs\BaseStandard\TestWeight类:
<?php
namespace App\Libs\BaseStandard;
use Closure;
class TestWeight
{
public function check($item, Closure $next)
{
if ($item['weight']['format'] > 10) {
$item['weight']['verify'] = 'success';
}
return $next($item);
}
}
写pipeline使用示例时参考了这篇文章,解释的清晰明了,对我帮助很大:https://learnku.com/laravel/t/7543/pipeline-pipeline-design-paradigm-in-laravel