管道,就是从一头进,另一头出,常用来处理一批具有先后顺序的连贯的操作,让需要终止管道,只需要返回false。
在Laravel中最常见的管道使用就是中间件了,比如 路由中间件。
对路由中间件的分析参考:https://blog.youkuaiyun.com/raoxiaoya/article/details/103462286
了解了管道的原理之后,我们就可以愉快的使用管道来处理我们的业务了。
比如:我需要对输入的内容做一个处理:增加时间,转化为大写,增加签名。
我们可以为每一个操作定义一个类。
1、定义接口或者契约
app\Services\DataProcessor\DataProcessorInterface.php
<?php
namespace App\Services\DataProcessor;
use Closure;
interface DataProcessorInterface
{
/**
* @param $data
* @param Closure $next
* @return mixed
*/
public function handle($data, Closure $next);
}
2、增加时间 的操作
app\Services\DataProcessor\AddPreTime.php
<?php
namespace App\Services\DataProcessor;
use Closure;
class AddPreTime implements DataProcessorInterface
{
public function handle($data, Closure $next)
{
$data['preTime'] = date('Y-m-d H:i:s');
return $next($data);
}
}
3、转化为大写 的操作
app\Services\DataProcessor\DataTransfer.php
<?php
namespace App\Services\DataProcessor;
use Closure;
use Illuminate\Support\Str;
class DataTransfer implements DataProcessorInterface
{
public function handle($data, Closure $next)
{
$data['contents'] = Str::upper($data['contents']);
return $next($data);
}
}
4、增加签名 的操作
app\Services\DataProcessor\AddEndSignature.php
<?php
namespace App\Services\DataProcessor;
use Closure;
use Illuminate\Support\Str;
class AddEndSignature implements DataProcessorInterface
{
public function handle($data, Closure $next)
{
$data['signature'] = Str::random(10);
return $next($data);
}
}
5、调用测试
我们使用 Illuminate\Pipeline\Pipeline 类
then 方法是必须的,传入一个闭包,表示最后会被处理的操作,可以在里面直接返回结果。
vie 方法设置统一调度的方法,默认handle,可以设置。
app\Console\Commands\DemoCommand.php
<?php
namespace App\Console\Commands;
use App\Services\DataProcessor\AddEndSignature;
use App\Services\DataProcessor\AddPreTime;
use App\Services\DataProcessor\DataTransfer;
use Illuminate\Console\Command;
use Illuminate\Pipeline\Pipeline;
class DemoCommand extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'DemoCommand';
/**
* The console command description.
*
* @var string
*/
protected $description = 'DemoCommand';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$pipes = [
AddPreTime::class,
DataTransfer::class,
AddEndSignature::class,
];
$data = ['contents'=>'asdhbybopwertyuip'];
$result = app(Pipeline::class)
->send($data)
->through($pipes)
->via('handle')
->then(function ($datas) {
return $datas;
});
$this->info(print_r($result, true));
}
}
别忘了注册到kernel.php
php artisan DemoCommand
打印结果:
Array
(
[contents] => ASDHBYBOPWERTYUIP
[preTime] => 2020-01-07 07:55:33
[signature] => xgqohTzlMq
)
当然实现同样的效果的方式很多,比如:观察者模式。