为什么 Route Middleware 不支持 terminate 呢? 有什么替代的解决方案?

想请教下

  1. routemidlleware 不支持 terminate 这是基于什么考虑的. 不管laravel还是lumen 只有global middleware才会去call terminate 而routemiddleware 却不会

  2. 像startSession这样的中间件. 在terminate中save. 如果不想手动save操作的话. 就必须把它定义为全局. 不改动框架源码的情况下 有什么好的思路?

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 8

@Alex89 额.. 我其实问的是"为什么" 而不是 "是不是"

8年前 评论

虽然文档写着不支持,但是查看源码和测试后发现是 Ok 的,注: 查看的是 5.1 的源码。

实现在 Illuminate\Foundation\Http\Kernel 类中,注意有调用 $this->gatherRouteMiddlewares($request) 获取路由中间件:

public function terminate($request, $response)
    {
        $middlewares = $this->app->shouldSkipMiddleware() ? [] : array_merge(
            $this->gatherRouteMiddlewares($request),
            $this->middleware
        );

        foreach ($middlewares as $middleware) {
            list($name, $parameters) = $this->parseMiddleware($middleware);

            $instance = $this->app->make($name);

            if (method_exists($instance, 'terminate')) {
                $instance->terminate($request, $response);
            }
        }

        $this->app->terminate();
    }
8年前 评论

@NauxLiu thx, 我没留意5.1的情况. 5.3中 lumen和laravel都已经改掉了.

Lumen5.3:

protected function callTerminableMiddleware($response)
    {
        if ($this->shouldSkipMiddleware()) {
            return;
        }

        $response = $this->prepareResponse($response);

        foreach ($this->middleware as $middleware) {
            if (! is_string($middleware)) {
                continue;
            }

            $instance = $this->make(explode(':', $middleware)[0]);

            if (method_exists($instance, 'terminate')) {
                $instance->terminate($this->make('request'), $response);
            }
        }
    }

目前如果需要在路由中间件中使用terminate 要么用后置中间件替代. 不然就得建立两个中间件. 一个全局单独处理terminate, 一个路由中间件处理主要逻辑比方说 session start. 只想到这两种方案了.

8年前 评论

看了下 5.3 最新的代码,还是保留了 routeMiddleware

https://github.com/laravel/framework/blob/...

file

8年前 评论

@tomcat9988 上面贴的是 Laravel 5.3, 看了下 Lumen 5.3 的代码,确实不支持 terminable 了...

8年前 评论

@mitoop terminate从字面上看是最终执行, 如果作者主要考虑用它来处理 "总是执行"的操作 那么你的说法是合理的.
但是从命名上看. 它更多的是 所有中间件执行后的最终调用 所以不是很同意你的这个看法.

8年前 评论

有种比较low的方法,在控制器return前将某个中间设置为全局中间件,这样,间接的实现了不同路由使用不同的终止中间件。
lumen中使用app()->middleware([ \App\Http\Middleware\CheckLogin::class]);,将中间件设置为全局中间件,然后在中间件中实现public function terminate($request, $response)方法即可。

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!