日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

js reduce实现中间件_Laravel中间件实现原理及实例分析

發布時間:2024/1/23 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 js reduce实现中间件_Laravel中间件实现原理及实例分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Laravel中間件實現原理詳解

本文實例講述了Laravel的中間件實現原理。分享給大家供大家參考,具體如下:

#1 什么是中間件?

對于一個Web應用來說,在一個請求真正處理前,我們可能會對請求做各種各樣的判斷,然后才可以讓它繼續傳遞到更深層次中。而如果我們用if else這樣子來,一旦需要判斷的條件越來越來,會使得代碼更加難以維護,系統間的耦合會增加,而中間件就可以解決這個問題。我們可以把這些判斷獨立出來做成中間件,可以很方便的過濾請求。

#2 Laravel中的中間件

在Laravel中,中間件的實現其實是依賴于Illuminate\Pipeline\Pipeline這個類實現的,我們先來看看觸發中間件的代碼。很簡單,就是處理后把請求轉交給一個閉包就可以繼續傳遞了。

public function handle($request, Closure $next) {

//do something for $request

return $next($request);

}

#3 中間件內部實現

上面說道,中間件是靠Pipeline來實現的,它的調用在Illuminate\Routing\Router中

return (new Pipeline($this->container))

->send($request)

->through($middleware)

->then(function ($request) use ($route) {

return $this->prepareResponse(

$request,

$route->run($request)

);

});

可以看到,中間件執行過程調用了三個方法。再來看看這三個方法的代碼:

send方法

public function send($passable){

$this->passable = $passable;

return $this;

}

其實send方法沒做什么事情,就是設置了需要在中間件中流水處理的對象,在這里就是HTTP請求實例。

through方法

public function through($pipes){

$this->pipes = is_array($pipes) ? $pipes : func_get_args();

return $this;

}

through方法也很簡單,就是設置一下需要經過哪些中間件處理。

then方法

真正難懂的來了,then方法代碼很簡潔,但是要理解可不容易。

public function then(Closure $destination){

//then方法接受一個閉包作為參數,然后經過getInitialSlice包裝,而getInitialSlice返回的其實也是一個閉包,如果還不知道什么是閉包先去看PHP文檔

$firstSlice = $this->getInitialSlice($destination);

//反轉中間件數組,主要是利用了棧的特性,用處接下來再說

$pipes = array_reverse($this->pipes);

//這個call_user_func先不要看,它其實就是執行了一個array_reduce返回的閉包

return call_user_func(

//接下來用array_reduce來用回調函數處理數組,建議先去PHP文檔讀懂array_reduce的執行原理。其實arrary_reduce什么事情都沒干,就是包裝閉包然后移交給call_user_func來執行

array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable

);

}

然后就沒有然后了,這樣就過完了所有中間件,是不是很優雅?

由于aray_reduce的第二個參數需要一個函數,我們這里重點看看getSlice()方法的源碼

protected function getSlice(){

return function ($stack, $pipe) { //這里$stack

return function ($passable) use ($stack, $pipe) {

if ($pipe instanceof Closure) {

return call_user_func($pipe, $passable, $stack);

} else {

list($name, $parameters) = $this->parsePipeString($pipe);

return call_user_func_array([$this->container->make($name), $this->method],

array_merge([$passable, $stack], $parameters));

}

};

};

}

看到可能會很頭暈,閉包返回閉包的。簡化一下就是getSlice()返回一個函數A,而函數A又返回了函數B。為什么要返回兩個函數呢?因為我們中間在傳遞過程中是用$next($request)來傳遞對象的,而$next($request)這樣的寫法就表示是執行了這個閉包,這個閉包就是函數A,然后返回函數B,可以給下一個中間件繼續傳遞。

再來簡化一下代碼就是:

//這里的$stack其實就是閉包,第一次遍歷的時候會傳入$firstSlice這個閉包,以后每次都會傳入下面的那個function; 而$pipe就是每一個中間件

array_reduce($pipes, function ($stack, $pipe) {

return function ($passable) use ($stack, $pipe) {

};

}, $firstSlice);

再來看這一段代碼:

//判斷是否為閉包,這里就是判斷中間件形式是不是閉包,是的話直接執行并且傳入$passable[請求實例]和$stack[傳遞給下一個中間件的閉包],并且返回

if ($pipe instanceof Closure) {

return call_user_func($pipe, $passable, $stack);

//不是閉包的時候就是形如這樣Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode執行

} else {

//解析,把名稱返回,這個$parameters看了許久源碼還是看不懂,應該是和參數相關,不過不影響我們的分析

list($name, $parameters) = $this->parsePipeString($pipe);

//從容器中解析出中間件實例并且執行handle方法

return call_user_func_array([$this->container->make($name), $this->method],

//$passable就是請求實例,而$stack就是傳遞的閉包

array_merge([$passable, $stack], $parameters));

}

再看一張圖片:

每一次迭代傳入上一次的閉包和需要執行的中間件,由于反轉了數組,基于棧先進后出的特性,所以中間件3第一個被包裝,中間件1就在最外層了。要記得,arrary_reduce他不執行中間件代碼,而是包裝中間件。

看到這里應該明白了,array_reduce最后會返回func3,那么call_user_func(func3,$this->passable)實際就是

復制代碼 代碼如下:

return call_user_func($middleware[0]->handle, $this->passable, func2);

而我們的中間件中的handle代碼是:

public function handle($request, Closure $next) {

return $next($request);

}

這里就相當于return func2($request),這里的$request就是經過上一個中間件處理過的。所以正果中間件的過程就完了,理解起來會有點繞,只要記得最后是由最外面的call_user_func來執行中間件代碼的

更多關于Laravel相關內容感興趣的讀者可查看本站專題:《Laravel框架入門與進階教程》、《php優秀開發框架總結》、《smarty模板入門基礎教程》、《php日期與時間用法總結》、《php面向對象程序設計入門教程》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總》

希望本文所述對大家基于Laravel框架的PHP程序設計有所幫助。

以上就是本次給大家分享的關于java的全部知識點內容總結,大家還可以在下方相關文章里找到相關文章進一步學習,感謝大家的閱讀和支持。

您可能感興趣的文章:

總結

以上是生活随笔為你收集整理的js reduce实现中间件_Laravel中间件实现原理及实例分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 韩国伦理片观看 | h网站在线观看 | 亚洲一本在线观看 | 成人午夜精品一区二区三区 | 日韩午夜在线播放 | 欧美一区二区三区视频在线 | 欧美8888| 国产一区二区三区色淫影院 | 日韩影院一区二区 | 三上悠亚ssⅰn939无码播放 | 健身教练巨大粗爽gay视频 | 欧美激情视频一区 | 亚洲黄v | 国产3p精品一区 | 一区二区三区中文字幕在线观看 | 国产精品一区二区三区久久久 | 久久精品美女 | 欧美激情视频二区 | 成 人免费va视频 | 五月激情在线观看 | 99国产精品久久久久久久久久久 | 三级在线免费 | www色天使| 天天都色| √资源天堂中文在线 | 欧美草草 | 66精品 | 免费国产在线观看 | 国产精品丝袜黑色高跟鞋的设计特点 | 色99视频 | 日韩久久久久久 | 日日摸夜夜添狠狠添欧美 | 波多野结衣一本一道 | 果冻传媒av| 久久久精品一区二区三区 | 男生和女生一起搞鸡 | 午夜看片在线观看 | 日韩性欧美 | 欧美视频导航 | 亚洲国产精品久久久久久6q | 久久大香焦 | 欧美又粗又深又猛又爽啪啪九色 | 女人特黄大aaaaaa大片 | 十八岁世界在线观看高清免费韩剧 | 国语对白对话在线观看 | 成人影视免费观看 | 日本三级中文字幕在线观看 | 国语粗话呻吟对白对白 | 国产精品黄色在线观看 | 天堂网91| 蜜臀在线播放 | 中文字幕在线播放日韩 | 国产成人麻豆免费观看 | 在线无码va中文字幕无码 | 免费激情视频网站 | 最新黄色av网站 | 国产男女视频在线观看 | 波多野结衣丝袜 | aaa午夜 | 爱爱网站视频 | 中国特级黄色大片 | 亚洲射吧 | 裸体毛片| 久久久久久久色 | 久久综合久色欧美综合狠狠 | 90岁老太婆乱淫 | 777在线视频 | 91在线观看免费高清完整版在线观看 | 色呦呦网站 | 日韩精品乱码久久久久久 | 亚洲乱码精品久久久久.. | 超碰在线天天 | 成年人免费在线观看视频网站 | 国产女主播福利 | www成人免费视频 | 日韩欧美成人免费视频 | 国产精品麻豆果冻传媒在线播放 | 第四色影音先锋 | 一级肉体全黄裸片 | 日韩欧美v| 成熟妇人a片免费看网站 | 国产精品98 | 黄色片在线免费看 | 日韩中文无 | 亚洲日本激情 | 色婷婷狠狠操 | 红桃视频亚洲 | 亚洲a黄| 久久久精品中文字幕 | 最新视频 - 8mav | 国产一区二区三区影视 | 尤果网福利视频在线观看 | 在线观看亚洲av每日更新 | 日韩在线视频播放 | 情侣作爱视频网站 | 国产一区二区三区四区 | 老头老夫妇自拍性tv | 日批视屏 | 国产精品一二三区 |