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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

slimphp中间件调用流程的理解

發布時間:2025/4/14 php 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 slimphp中间件调用流程的理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

slimphp是一款微型php框架,主要是處理http請求,并調用合適的程序處理,并返回一個http響應。

它遵循php的psr7規范,可以很方便的集成其它遵循psr7規范的php組建。

當讀到中間件時,官網給出了,如下所示的圖

?

試驗如下:

$mw1 = function ($request, $response, $next) {echo('middleware 1 start <br>');$response = $next($request, $response);echo('middleware 1 end <br>');return $response; };$mw2 = function ($request, $response, $next) {echo('middleware 2 start <br>');$response = $next($request, $response);echo('middleware 2 end <br>');return $response; };$app->get('/mw', function ($request, $response, $args) {echo(' Hello <br>');return $response; })->add($mw1)->add($mw2);

輸出為:

middleware 2 start?
middleware 1 start?
middleware 1 end?
middleware 2 end?
Hello?

不難看出實際是 1、調用$mw2 輸出?middleware 2 start ? 2、調用$mw2里的$next即$mw1 輸出middleware 1 start? 3、$mw1再調用$next,而此時沒有中間件了,直接輸出了middleware 1 end ? 4、由于$mw2還沒return,還在調用棧里,接著輸出middleware 2 end 5、對于這個hello我覺得甚是奇怪,按照官網文檔,應當在中間輸出才對。

于是開始調試跟蹤,發現原來如此:

在vendor\slim\slim\Slim\MiddlewareAwareTrait.php里有如下代碼:

protected function addMiddleware(callable $callable) {if ($this->middlewareLock) {throw new RuntimeException('Middleware can’t be added once the stack is dequeuing');}if (is_null($this->stack)) {$this->seedMiddlewareStack();}$next = $this->stack->top();$this->stack[] = function (ServerRequestInterface $req, ResponseInterface $res) use ($callable, $next) {$result = call_user_func($callable, $req, $res, $next);if ($result instanceof ResponseInterface === false) {throw new UnexpectedValueException('Middleware must return instance of \Psr\Http\Message\ResponseInterface');}return $result;};return $this; }

?

?$next 即參數為ServerRequestInterface $req, ResponseInterface $res的閉包,而$callable即我們的中間件。

中間件都添加到堆棧$this->stack[]上了,$next則是棧頂,而$this->seedMiddlewareStack();則把路由中間件第一個壓棧了。

這就是官網調用順序的流程了。

?

然而Hello 為何最后輸出則還是費解,于是繼續調試。

在vendor\slim\slim\Slim\Route.php里發現了痕跡:

__invoke函數中

if ($this->outputBuffering === false) {$newResponse = $handler($this->callable, $request, $response, $this->arguments);} else {try {ob_start();$newResponse = $handler($this->callable, $request, $response, $this->arguments);$output = ob_get_clean();} catch (Exception $e) {ob_end_clean();throw $e;}}

關鍵是$output = ob_get_clean();

我們的echo輸出被路由中間件攔截了,并放入了$response->getBody()->write($output);

if (!empty($output) && $response->getBody()->isWritable()) {if ($this->outputBuffering === 'prepend') {// prepend output buffer content$body = new Http\Body(fopen('php://temp', 'r+'));$body->write($output . $response->getBody());$response = $response->withBody($body);} elseif ($this->outputBuffering === 'append') {// append output buffer content$response->getBody()->write($output);}}

在$response返回時才會輸出,所以上面的Hello?是最后輸出的。

那為啥$mw1、$mw2沒有這個問題呢,因為我們的中間件就是直接輸出,并不像路由中間件這么處理。

?

轉載于:https://www.cnblogs.com/xdao/p/slim_middleware_thinking.html

總結

以上是生活随笔為你收集整理的slimphp中间件调用流程的理解的全部內容,希望文章能夠幫你解決所遇到的問題。

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