Heim  >  Artikel  >  Backend-Entwicklung  >  Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

不言
不言Original
2018-07-10 14:30:582580Durchsuche

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-Designmuster

Wenn die Wasserleitung zu lang ist, wird sie undicht, wenn ein Teil kaputt geht, und sie ist nicht zum Biegen und Drehen in komplexen Umgebungen geeignet. Daher werden wir die Wasserleitungen in sehr kurze Rohre unterteilen und dann die Größe der Rohre maximieren, um unterschiedliche Funktionen zu erfüllen, sie an die örtlichen Gegebenheiten anzupassen und sie zusammenzubauen, um eine Vielzahl unterschiedlicher Anforderungen zu erfüllen.

Dies 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/pipelineSchluck

Das erste Mal, dass ich das Konzept der „Pfeife“ kennengelernt habe, war die Verwendung von

.

gulp

Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

ist ein automatischer Task-Runner, der auf

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' ]);
UnixDie 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. lessjsIlluminatePipeline

Die Middleware im Laravel-Framework wird mit

implementiert. Ursprünglich wollte ich über meine Interpretation des „Laravel-Middleware“-Quellcodes schreiben, habe aber festgestellt, dass es bereits welche gibt viele online Der Beitrag hat es bereits erklärt, daher wird in diesem Artikel lediglich die Verwendung von

erläutert. IlluminatePipelineIlluminatePipeline

Schreiben Sie eine Demo

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;
        });
}


Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

Über die Analyse des PHP-Pipeline-Plug-Ins League\PipelineFü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

Die einfache Verwendung von

und

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. gulpIlluminatePipelineLassen Sie mich nun einen Blick auf den Quellcode des

-Plug-Ins werfen, um zu sehen, wie es implementiert ist.

LeaguePipeline

Kurze Beschreibung

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.

https://pipeline. thephpleague.com/

Installieren Sie das Plug-in

composer require league/pipeline

Schreiben Sie eine Demo

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;
    }
);

Führen Sie das Ergebnis aus

Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

Interpretieren Sie den Quellcode

Das gesamte Plug- in hat nur diese Dateien:

Über die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline

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);
}
Diese Schnittstelle nutzt hauptsächlich die Idee der Kettenprogrammierung, um kontinuierlich Pipelines hinzuzufügen „pipe“ und fügt dann eine magische Methode hinzu, um die übergebenen Parameter auszuführen.

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 的作用主要就是两个:

  1. 添加组装各个管道「pipe」;

  2. 组装后,引水流动,执行 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中文网!

相关推荐:

关于PHP开发中遇到的一些错误的解决方法

关于利用Vue-laravel前端和后端分离写一个博客的方法

Das obige ist der detaillierte Inhalt vonÜber die Analyse des PHP-Pipeline-Plug-Ins League\Pipeline. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn