成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

php管道模式手測

zzir / 1451人閱讀

摘要:所以管道模式大致需要三個(gè)角色管道,閥門和載荷流水。模仿返回處理后的結(jié)果輸出結(jié)語上面的代碼并沒有達(dá)到中間件的真正執(zhí)行部分,例子中只是用到了管道模式的一部分。

一直在用Laravel框架,很喜歡laravel框架的中間件。在請求到結(jié)果之前,如果我們想要對路由或請求進(jìn)行額外的處理,簡單的加個(gè)Midleware中間件就行了,很簡單,很方便是不是。
最近幾天看了下它的中間件的實(shí)現(xiàn)方式,把自己的心得感悟?qū)懴聛矸窒斫o大家。

了解管道模式

laravel的中間件用的是管道模式,我們先知道管道模式是什么:

所謂管道(Pipeline)設(shè)計(jì)模式就是將會(huì)數(shù)據(jù)傳遞到一個(gè)任務(wù)序列中,管道扮演者流水線的角色,數(shù)據(jù)在這里被處理然后傳遞到下一個(gè)步驟

管道,顧名思義,就是一個(gè)長長的流水管道,只不過加了許多閥門。所以管道模式大致需要三個(gè)角色:管道,閥門和載荷(流水)。如下圖:

管道模式UML模型圖

開始代碼之前,我們必須先了解管道模式的模型圖

簡單的實(shí)現(xiàn)

根據(jù)上面的模型圖,我們來實(shí)現(xiàn)自己所理解的管道模式的代碼:

/**
 * PipelineBuilder 接口 即管道
 * @method pipe 存入多個(gè)閥門
 * @method process 輸出
 */
interface PipelineBuilderInterface
{
    public function __construct($payload);
    public function pipe(StageBuilderInterface $stage);
    public function process();
}
// 具體的管道類
class Pipeline implements PipelineBuilderInterface
{
    protected $payload;
    protected $pipes = [];
    public function __construct($payload)
    {
        $this->payload = $payload;
    }

    public function pipe(StageBuilderInterface $stage)
    {
        $this->pipes[] = $stage;

        return $this;
    }

    public function process()
    {
        foreach ($this->pipes as $pipe) {
            call_user_func([$pipe, "handle"], $this->payload);
        }
    }
}
// 閥門接口
interface StageBuilderInterface
{
    public function handle($payload);
}
// 具體的閥門類
class StageOneBuilder implements StageBuilderInterface
{
    public function handle($payload)
    {
        echo $payload ." 真是個(gè)";
    }
}
// 具體的閥門類
class StageTwoBuilder implements StageBuilderInterface
{
    public function handle($payload)
    {
        echo "帥氣的男人";
    }
}
// 輸出:我真是個(gè)帥氣的男人
$pipeline = new Pipeline("我");
$pipeline->pipe(new StageOneBuilder)
    ->pipe(new StageTwoBuilder)
    ->process();
底層源碼

先來看看它的底層源碼:

return (new Pipeline($this->container))
            ->send($request)
            ->through($middleware)
            ->then(function ($request) use ($route) {
                return $this->prepareResponse(
                    $request, $route->run()
                );
            });

上面的代碼是處理request請求的一部分代碼,send()獲取待處理的數(shù)據(jù),through()獲取中間件,then()傳遞閉包函數(shù)。
基本上,使用laravel pipelines你可以將一個(gè)實(shí)例對象(object)在多個(gè)類之間傳遞,就像流水順著管道依次流淌一般,最終呢,層層傳遞,你就得到了從頭至尾一系列執(zhí)行操作的“最終”結(jié)果。

模仿laravel pipeline
interface PipelineInterface
{
    public function send($traveler);
    public function through($stops);
    public function via($method);
    public function process();
}

interface StageInterface
{
    public function handle($payload);
}

class StageOne implements StageInterface
{
    public function handle($payload) 
    {
        echo $payload . " am really an ";
    }
} 

class StageTwo implements StageInterface
{
    public function handle($payload) {
        echo "awesome man";
    }
} 

class Pipe implements PipelineInterface
{
    protected $container;
    protected $passable;
    protected $pipes = [];
    protected $via = "handle";

    public function __construct($container)
    {
        $this->container = $container;
    }

    public function send($passable)
    {
        $this->passable = $passable;

        return $this;
    }

    public function through($pipes)
    {
        $this->pipes = is_array($pipes) ? $pipes : func_get_args();

        return $this;
    }

    public function via($method)
    {
        $this->via = $method;

        return $this;
    }

    public function process()
    {
        foreach ($this->pipes as $pipe) {
            // 返回處理后的結(jié)果
            $this->passable = call_user_func([$pipe, $this->via], $this->passable);
        }
    }
}
$container = "a";
$payload = "wa";
$pipe = new Pipe($container);

// 輸出:I am really an awesome man
$pipe->send($payload)->through([(new StageOne), (new StageTwo)])->process();
結(jié)語

上面的代碼并沒有達(dá)到laravel中間件的真正執(zhí)行部分,例子中只是用到了管道模式的一部分。像then()方法中還用了array_reducearray_reverse函數(shù)來處理請求,這一部分有時(shí)間會(huì)進(jìn)一步研究。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31352.html

相關(guān)文章

  • 從0到1優(yōu)雅的實(shí)現(xiàn)PHP多進(jìn)程管理

    摘要:目的綜上所述,我的目標(biāo)就是實(shí)現(xiàn)基于模式實(shí)現(xiàn)的多進(jìn)程管理工具。備注下文中,父進(jìn)程統(tǒng)稱為子進(jìn)程統(tǒng)稱為。最后我們通過下圖來簡單的總結(jié)和描述這個(gè)多進(jìn)程實(shí)現(xiàn)的過程控制上面實(shí)現(xiàn)了多進(jìn)程和多進(jìn)程的常駐內(nèi)存,那如何去管理呢答案多進(jìn)程通信。 _ | | _ __ __ _ _ __...

    lakeside 評論0 收藏0
  • PHP 命令行方式實(shí)現(xiàn)異步多進(jìn)程模式的任務(wù)處理

    摘要:定義任務(wù)處理方法。讀取來自命令行的參數(shù),開始執(zhí)行任務(wù)。該函數(shù)有兩個(gè)參數(shù)和,是引用類型,用來存儲(chǔ)子進(jìn)程的狀態(tài),有兩個(gè)可選常量,分別表示不等待子進(jìn)程結(jié)束立即返回和等待子進(jìn)程結(jié)束。 用PHP來實(shí)現(xiàn)異步任務(wù)一直是個(gè)難題,現(xiàn)有的解決方案中:PHP知名的異步框架有 swoole 和 Workerman,但都是無法在 web 環(huán)境中直接使用的,即便強(qiáng)行搭建 web 環(huán)境,異步調(diào)用也是使用多進(jìn)程模式實(shí)...

    Invoker 評論0 收藏0
  • PHP 進(jìn)程的實(shí)現(xiàn)與管理

    摘要:運(yùn)行模式實(shí)現(xiàn)進(jìn)程前,需了解常見的的運(yùn)行模式通用網(wǎng)關(guān)接口模式模式命令行模式模塊模式作為服務(wù)器模塊而進(jìn)程則是使用命令行模式運(yùn)行的基本實(shí)現(xiàn)中提供了一個(gè)擴(kuò)展,可以利用操作系統(tǒng)的調(diào)用來實(shí)現(xiàn)多進(jìn)程。 應(yīng)用場景 一些耗時(shí)任務(wù): 大數(shù)據(jù)表分表后的統(tǒng)計(jì)信息功能 分批發(fā)送短信或郵件功能 其他可分目標(biāo)的任務(wù)功能(很多種) 所以我們就需要一個(gè)常駐內(nèi)存的任務(wù)管理工具,為了保證實(shí)時(shí)性,一方面我們讓它一直執(zhí)行任...

    MockingBird 評論0 收藏0
  • PHP 進(jìn)程的實(shí)現(xiàn)與管理

    摘要:運(yùn)行模式實(shí)現(xiàn)進(jìn)程前,需了解常見的的運(yùn)行模式通用網(wǎng)關(guān)接口模式模式命令行模式模塊模式作為服務(wù)器模塊而進(jìn)程則是使用命令行模式運(yùn)行的基本實(shí)現(xiàn)中提供了一個(gè)擴(kuò)展,可以利用操作系統(tǒng)的調(diào)用來實(shí)現(xiàn)多進(jìn)程。 應(yīng)用場景 一些耗時(shí)任務(wù): 大數(shù)據(jù)表分表后的統(tǒng)計(jì)信息功能 分批發(fā)送短信或郵件功能 其他可分目標(biāo)的任務(wù)功能(很多種) 所以我們就需要一個(gè)常駐內(nèi)存的任務(wù)管理工具,為了保證實(shí)時(shí)性,一方面我們讓它一直執(zhí)行任...

    testbird 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<