Dieser Artikel stellt hauptsächlich die Analyse des PHP-Pipeline-Plug-Ins LeaguePipeline vor. Es hat einen gewissen Referenzwert. Jetzt kann ich es mit allen Freunden teilen, die es benötigen.
Pipeline-DesignmusterDies führt zum Entwurfsmuster von Pipeline, das darin besteht, komplexe und langwierige Prozesse in kleine Prozesse und Aufgaben zu zerlegen. Jede minimal quantifizierte Aufgabe kann durch die Zusammenstellung verschiedener kleiner Aufgaben wiederverwendet werden, um komplexe und vielfältige Prozesse zu bilden.
Führen Sie abschließend die „Eingabe“ in die Pipeline ein, bearbeiten (verarbeiten, filtern) Sie die Eingabe entsprechend jeder kleinen Aufgabe und geben Sie schließlich die Ergebnisse aus, die den Anforderungen entsprechen.
Heute werde ich hauptsächlich „Pipeline“ lernen. Ich empfehle übrigens ein PHP-Plugin:
.league/pipeline
Schluck
gulp
basiert. Er kann das Testen von gulp
, NodeJS
, Javascript
und anderen Dateien automatisch abschließen . Überprüfen, zusammenführen, komprimieren, formatieren, den Browser automatisch aktualisieren, Bereitstellungsdateien generieren und die Dateien überwachen, um die angegebenen Schritte nach Änderungen zu wiederholen. In Bezug auf die Implementierung greift sie auf die Pipe-Idee des sass
-Betriebssystems zurück. Die Ausgabe der vorherigen Ebene wird direkt zur Eingabe der nächsten Ebene, was die Bedienung sehr einfach macht. less
var gulp = require('gulp'); var less = require('gulp-less'); var minifyCSS = require('gulp-csso'); var concat = require('gulp-concat'); var sourcemaps = require('gulp-sourcemaps'); gulp.task('css', function(){ return gulp.src('client/templates/*.less') .pipe(less()) .pipe(minifyCSS()) .pipe(gulp.dest('build/css')) }); gulp.task('js', function(){ return gulp.src('client/javascript/*.js') .pipe(sourcemaps.init()) .pipe(concat('app.min.js')) .pipe(sourcemaps.write()) .pipe(gulp.dest('build/js')) }); gulp.task('default', [ 'html', 'css', 'js' ]);
Unix
Die beiden oben genannten dienen hauptsächlich dem Parsen, Komprimieren, Ausgeben und anderen Prozessvorgängen für und alle task
-Dateien und das anschließende Speichern der Ausgabe jedes Schritts im entsprechenden Ordner des Vorgangs Es ist der Input für den nächsten Vorgang, genau wie der Wasserfluss in einem Rohr. less
js
IlluminatePipeline
erläutert. IlluminatePipeline
IlluminatePipeline
public function demo(Request $request)
{
$pipe1 = function ($payload, Closure $next) {
$payload = $payload + 1;
return $next($payload);
};
$pipe2 = function ($payload, Closure $next) {
$payload = $payload * 3;
return $next($payload);
};
$data = $request->input('data', 0);
$pipeline = new Pipeline();
return $pipeline
->send($data)
->through([$pipe1, $pipe2])
->then(function ($data) {
return $data;
});
}
Für Zur Analyse des Quellcodes können Sie die Lektüre dieses Artikels empfehlen. Die Analyse ist recht gründlich:
Implementierung der Laravel-Pipeline-Komponente https://www.insp.top/article/realization-of-pipeline-component -for -laravel
LeaguePipeline
oben zeigt uns nur, dass „Pipeline“ weit verbreitet ist. Wenn wir gebeten würden, selbst ein ähnliches Plug-in zu schreiben, wäre das meiner Meinung nach nicht schwierig. gulp
IlluminatePipeline
Lassen Sie mich nun einen Blick auf den Quellcode des
LeaguePipeline
Dieses Paket bietet eine Plug-and-Play-Implementierung des Pipeline-Musters. Es handelt sich um ein Architekturmuster, das sequentielle Prozesse kapselt und Abgleich von Operationen und Pipelines, um neue Ausführungsketten zu erstellen. Das Pipeline-Muster wird oft mit einer Produktionslinie verglichen, bei der jede Stufe eine bestimmte Operation an einer bestimmten Nutzlast/einem bestimmten Thema ausführt. Die Stufen können darauf reagieren, sie manipulieren, dekorieren oder sogar ersetzen die Nutzlast.
Wenn Sie feststellen, dass Sie Ergebnisse von einer Funktion an eine andere übergeben, um eine Reihe von Aufgaben zu einem bestimmten Thema abzuschließen, möchten Sie diese möglicherweise in eine Pipeline umwandeln.Installieren Sie das Plug-inhttps://pipeline. thephpleague.com/
composer require league/pipeline
use League\Pipeline\Pipeline;
// 创建两个闭包函数
$pipe1 = function ($payload) {
return $payload + 1;
};
$pipe2 = function ($payload) {
return $payload * 3;
};
$route->map(
'GET',
'/demo',
function (ServerRequestInterface $request, ResponseInterface $response
) use ($service, $pipe1, $pipe2) {
$params = $request->getQueryParams();
// 正常使用
$pipeline1 = (new Pipeline)
->pipe($pipe1)
->pipe($pipe2);
$callback1 = $pipeline1->process($params['data']);
$response->getBody()->write("<h1>正常使用</h1>");
$response->getBody()->write("<p>结果:$callback1</p>");
// 使用魔术方法
$pipeline2 = (new Pipeline())
->pipe($pipe1)
->pipe($pipe2);
$callback2 = $pipeline2($params['data']);
$response->getBody()->write("<h1>使用魔术方法</h1>");
$response->getBody()->write("<p>结果:$callback2</p>");
// 使用 Builder
$builder = new PipelineBuilder();
$pipeline3 = $builder
->add($pipe1)
->add($pipe2)
->build();
$callback3 = $pipeline3($params['data']);
$response->getBody()->write("<h1>使用 Builder</h1>");
$response->getBody()->write("<p>结果:$callback3</p>");
return $response;
}
);
Interpretieren Sie den Quellcode
Das gesamte Plug- in hat nur diese Dateien:
PipelineInterface<?php declare(strict_types=1);
namespace League\Pipeline;
interface PipelineInterface extends StageInterface
{
/**
* Create a new pipeline with an appended stage.
*
* @return static
*/
public function pipe(callable $operation): PipelineInterface;
}
interface StageInterface
{
/**
* Process the payload.
*
* @param mixed $payload
*
* @return mixed
*/
public function __invoke($payload);
}
Lassen Sie uns einen Blick darauf werfen, was diese magische Methode bewirkt:
mixed __invoke ([ $... ] )
当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。如:
<?php class CallableClass { function __invoke($x) { var_dump($x); } } $obj = new CallableClass; $obj(5); var_dump(is_callable($obj)); ?>
返回结果:
int(5) bool(true)
Pipeline
<?php declare(strict_types=1); namespace League\Pipeline; class Pipeline implements PipelineInterface { /** * @var callable[] */ private $stages = []; /** * @var ProcessorInterface */ private $processor; public function __construct(ProcessorInterface $processor = null, callable ...$stages) { $this->processor = $processor ?? new FingersCrossedProcessor; $this->stages = $stages; } public function pipe(callable $stage): PipelineInterface { $pipeline = clone $this; $pipeline->stages[] = $stage; return $pipeline; } public function process($payload) { return $this->processor->process($payload, ...$this->stages); } public function __invoke($payload) { return $this->process($payload); } }
其中核心类 Pipeline
的作用主要就是两个:
添加组装各个管道「pipe」;
组装后,引水流动,执行 process($payload),输出结果。
Processor
接好各种管道后,那就要「引水入渠」了。该插件提供了两个基础执行类,比较简单,直接看代码就能懂。
// 按照 $stages 数组顺利,遍历执行管道方法,再将结果传入下一个管道,让「水」一层层「流动」起来 class FingersCrossedProcessor implements ProcessorInterface { public function process($payload, callable ...$stages) { foreach ($stages as $stage) { $payload = $stage($payload); } return $payload; } } // 增加一个额外的「过滤网」,经过每个管道后的结果,都需要 check,一旦满足则终止,直接输出结果。 class InterruptibleProcessor implements ProcessorInterface { /** * @var callable */ private $check; public function __construct(callable $check) { $this->check = $check; } public function process($payload, callable ...$stages) { $check = $this->check; foreach ($stages as $stage) { $payload = $stage($payload); if (true !== $check($payload)) { return $payload; } } return $payload; } } interface ProcessorInterface { /** * Process the payload using multiple stages. * * @param mixed $payload * * @return mixed */ public function process($payload, callable ...$stages); }
我们完全也可以利用该接口,实现我们的方法来组装管道和「过滤网」。
PipelineBuilder
最后提供了一个 Builder,这个也很好理解:
class PipelineBuilder implements PipelineBuilderInterface { /** * @var callable[] */ private $stages = []; /** * @return self */ public function add(callable $stage): PipelineBuilderInterface { $this->stages[] = $stage; return $this; } public function build(ProcessorInterface $processor = null): PipelineInterface { return new Pipeline($processor, ...$this->stages); } } interface PipelineBuilderInterface { /** * Add an stage. * * @return self */ public function add(callable $stage): PipelineBuilderInterface; /** * Build a new Pipeline object. */ public function build(ProcessorInterface $processor = null): PipelineInterface; }
无论是对不同技术的横向理解,还是基于 Laravel 或者某些开源插件,我们都能学习到技术之上的通用原理和方法。再将这些原理和方法反作用于我们的实际代码开发中。
最近闲来没事,自己参考 Laravel 去写个简易框架,也将League\Pipeline
引入到框架中使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
关于利用Vue-laravel前端和后端分离写一个博客的方法
Das obige ist der detaillierte Inhalt vonÜber die Analyse des PHP-Pipeline-Plug-Ins LeaguePipeline. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!