前回に紹介したLaravelのグローバルミドルウェアですが、必要に応じてカスタムのミドルウェアを作成することも可能です。今回は、入力文に含まれる禁止用語を自動的に隠す(***で置換する)ミドルウェアを例として作成します。

禁止用語を隠すミドルウェア

まず、artisanで空のミドルウェアを作成して、

$ php artisan make:middleware HideForbiddenWords

そのファイルを以下のように編集します。

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Str;
use Illuminate\Http\Request;

class HideForbiddenWords
{
    public static $forbiddenWords = ['禁止1', '禁止2', '禁止3'];

    public function handle(Request $request, Closure $next): mixed
    {
        // 禁止用語を***に変換
        $all = $request->collect()->map(function ($value, $key) {
            return is_string($value) ? Str::of($value)->replace(static::$forbiddenWords, '***')->toString() : $value;
        })->all();

    // もとのリクエストを置き換える
        $request->merge($all); 

        return $next($request);
    }
}

$forbiddenWords配列で設定した3つの禁止用語が入力にあれば、***に変換します。

tinkerで試してみましょう。

> $request = app('request');
> $request->merge(['sentence' => '私は「禁止1」と叫んでしまいました。'])->all();
= [
    "sentence" => "私は「禁止1」と叫んでしまいました。",
  ]

> use App\Http\Middleware\HideForbiddenWords;
> (new HideForbiddenWords)->handle($request, fn($request) => $request)->all();
= [
    "sentence" => "私は「***」と叫んでしまいました。",
  ]

期待した結果になりました。

グローバルミドルウェアに追加

作成したミドルウェアをグローバルのミドルウェアとして設定するには、ブートストラップに使用されるapp.phpを編集します。
以下は、Laravel 11.xで作成されたデフォルトのファイルで、ここのwithMiddlewareのクロージャでappendするだけです。

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(
            \App\Http\Middleware\HideForbiddenWords::class,
        );
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

このミドルウェアは、前回に紹介したデフォルトのグローバルミドルウェア(以下)

> use Illuminate\Foundation\Configuration\Middleware;
 
> (new Middleware)->getGlobalMiddleware();
= [
    "Illuminate\Foundation\Http\Middleware\InvokeDeferredCallbacks",
    "Illuminate\Http\Middleware\TrustProxies",
    "Illuminate\Http\Middleware\HandleCors",
    "Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance",
    "Illuminate\Http\Middleware\ValidatePostSize",
    "Illuminate\Foundation\Http\Middleware\TrimStrings",
    "Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull",
  ]

の最後のConvertEmptyStringsToNullの次に実行されることになります。

プロジェクトのコントローラのすべてにおいてこのミドルウェアが適用されるのが大げさなら、以下のようにroutes/web.phpにおいて、特定のルートだけにミドルウェアを装着することも可能です。

use App\Http\Middleware\HideForbiddenWords;

Route::patch('/profile', [ProfileController::class, 'update'])
    ->name('profile.update')
    ->middleware(HideForbiddenWords::class);
メルマガ購読の申し込みはこちらから。

By khino