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

想请教下

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

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

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 8

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

7年前 评论

虽然文档写着不支持,但是查看源码和测试后发现是 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();
    }
7年前 评论

@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. 只想到这两种方案了.

7年前 评论

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

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

file

7年前 评论

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

7年前 评论

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

7年前 评论

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

6年前 评论

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