🥪

【Laravel】終了処理ミドルウェアを試してみる

2024/01/19に公開
2

この記事について

Laravelのミドルウェアの終了処理(terminateメソッド)をちょっと触ってみた記事です。
(本当に触ってみただけの記事です)

何か改善点などあればご指摘ください 🙏

終了処理ミドルウェアとは

HTTPレスポンスがブラウザに送信された後、ミドルウェアが何らかの作業を行う必要がある場合があります。ミドルウェアでterminateメソッドを定義し、WebサーバがFastCGIを使用している場合、レスポンスがブラウザに送信された後、terminateメソッドが自動的に呼び出されます。
https://readouble.com/laravel/10.x/ja/middleware.html

レスポンスの送信後に行いたい処理を実行できるようです🧐

実際に触ってみる

Laravel環境の構築

Laravelの環境はLaravel Sailで構築します。
(別にMySQLは使わないのですが、何も指定しないとRedisやmeilisearchなど諸々追加されてしまうので)
curl -s "https://laravel.build/middleware-test?with=mysql" | bash

./vendor/bin/sail upでコンテナを起動します。

ミドルウェアの作成

Laravelアプリケーションコンテナの中に入り、をミドルウェアを作成します。

php artisan make:middleware TestTerminate

app/Http/Middleware/TestTerminate.php
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class TestTerminate
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        return $next($request);
    }
}

ミドルウェアが実行されるように登録する

終了処理ミドルウェアを定義したら、それをapp/Http/Kernel.phpファイルのルートまたはグローバルミドルウェアのリストに追加する必要があります。

↑とのことなので、app/Http/Kernel.phpの配列に追加します😺

app/Http/Kernel.php
protected $middleware = [
    (他のミドルウェア)
    \App\Http\Middleware\TestTerminate::class,
];

終了処理を定義する

handleメソッドの下に定義します。

app/Http/Middleware/TestTerminate.php

    use Illuminate\Support\Facades\Log;

    (省略)

    public function terminate(Request $request, Response $response)
    {
        Log::debug("terminate実行");
    }

実行してみる

http://localhost:80にアクセスしてから、storage/logs/larave.logをチェックします。

storage/logs/larave.log
[2024-01-19 11:03:56] local.DEBUG: terminate実行  

terminateが呼び出されてますね!

おわりに

レスポンス送信後に実行すればいい処理を書く際に使用する感じですかね…🧐

WebサーバがFastCGIを使用している場合、レスポンスがブラウザに送信された後、terminateメソッドが自動的に呼び出されます。

↑これってFastCGIを使っていない場合って動かないんでしょうか…?
(そもそもFastCGIの理解が曖昧なので、変な疑問かもしれませんが…。)


FastCGIでない場合は、レスポンスが送信される前に動くようです!
こちらの記事で調べてくださっていました🙏

GitHubで編集を提案

Discussion

nshironshiro

FastCGI でない場合は、レスポンスがブラウザに送信される前に処理されるという感じですね。
私が以前書いた記事も参考までに。
https://zenn.dev/nshiro/articles/f165468a4f4d53

まさとまさと

ありがとうございます🙏

記事で検証してくださっているように、FastCGIではない場合は3秒待ってから画面が描画されている→レスポンス送信前にterminateが実行されているんですね…。

お答えいただきありがとうございました🙇