摘要:所以管道模式大致需要三個(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è)角色:管道,閥門和載荷(流水)。如下圖:
開始代碼之前,我們必須先了解管道模式的模型圖
根據(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é)果。
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_reduce和array_reverse函數(shù)來處理請求,這一部分有時(shí)間會(huì)進(jìn)一步研究。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31352.html
摘要:目的綜上所述,我的目標(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)程通信。 _ | | _ __ __ _ _ __...
摘要:定義任務(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í)...
摘要:運(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í)行任...
摘要:運(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í)行任...
閱讀 2438·2021-11-18 10:02
閱讀 699·2021-10-08 10:04
閱讀 2277·2021-09-03 10:51
閱讀 3558·2019-08-30 15:44
閱讀 2811·2019-08-29 14:09
閱讀 2477·2019-08-29 12:21
閱讀 2074·2019-08-26 13:45
閱讀 1815·2019-08-26 13:25