Console 生命周期中的 Lumen 自定义中间件

Lumen custom middleware in Console lifecycle

我正在尝试为我的命令 运行 创建一个日志记录中间件。 记录器在用户发出 HTTP 请求时工作,但我不知道如何在调用预定命令时使其工作。

有人可以帮忙吗?

class LoggingMiddleware {

  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure  $next
   * @return mixed
   */
  public function handle($request, Closure $next) {
    return $next($request);
  }

  /**
   * Perform any final actions for the request lifecycle.
   *
   * @param  Request  $request
   * @param  Response  $response
   * @return void
   */
  public function terminate($request, $response) {
    dd('HELLOWORLD');
  }
}

然后我在框架上注册它:

$app->middleware([
  App\Http\Middleware\LoggingMiddleware::class
]);

因此,如果控制台和 Http 请求的生命周期与我在文档中看到的相同,这不应该也适用于控制台端吗?

由于 terminate 方法的性质,您不能在 artisan 命令中使用它,来自 laravel docs:

If you define a terminate method on your middleware, it will automatically be called after the response is ready to be sent to the browser.

这说明了终止的行为,并且由于它是响应准备发送到浏览器的状态指示器,因此在控制台命令的情况下它不会这样做。

此外,如果您深入研究 laravel 源代码,您会发现两个内核(http 和控制台内核)在最后一个阶段处理生命周期的方式略有不同。确实,它们在 handle 方法方面具有相同的生命周期,但它们在终止时具有不同的行为:

控制台内核只调用 $this->app->terminate(); 来终止整个应用程序,而 http 内核也会在调用应用程序终止之前执行 $this->terminateMiddleware($request, $response);。因此,这就是终止方法对控制台命令不起作用的原因。

因此,为了在命令末尾记录日志,您应该将其放在句柄函数的末尾。或者您可以定义自己的终止函数,该函数必须手动调用。

我希望这能回答你的问题。