🛡️

Laravel 8.55~ やや存在感薄めの safe メソッドで遊んでみる

2021/09/21に公開

はじめに

Ver.8.55で新規追加され、その後、8.56、8.58で少し機能追加された safe メソッド(バリデーション済みデータ取得用メソッド)を試してみました。

参考:本家ドキュメント
参考:[8.x] Validated subsets #38366
参考:ValidatedInput.php

本題

Laravel では、コントローラ又は FromRequest でバリデーションして、validate() / validated() メソッドを呼び出すと、そのバリデーションの対象になった項目だけを返すのは、まぁ、Laravel やっている人なら知っている所ですが、これは、単なる配列なので、やや微妙だった所もあると思います。

そこで、safe() なるメソッドが加わり、これを呼び出すと、ValidatedInput というオブジェクトが返され、->only() やら ->except() などが呼び出せるようになりました。もちろん、バリデーションの対象になったデータに限られ取得されます。

ということで、以下試したサンプルです。
(紙面の都合上、FormRequest ではなく、コントローラでやっています。どちらも結果は同じです)

URLは、/?name=taro&age=35&hobby=tennis&abc=123 で呼び出しています。
最後の &abc=123 は、バリデーションの対象外なので、どの結果にも含まれません。

Route::get('/', function (Request $request) {
    $validator = validator($request->all(), [
        'name' => ['required'],
        'age' => ['required'],
        'hobby' => ['required'],
    ]);

    // safe() の前に validate() やら fails() を呼び出して、適切にエラー処理する
    // 例
    $validator->validate();

    // 例
    if ($validator->fails()) {
        return redirect('...')
            ->withErrors($validator)
            ->withInput();
    }

    dd($validator->safe()->only('name'));
    dd($validator->safe()->except('name'));
    dd($validator->safe()->merge(['hoge' => 'bar']));
    dd($validator->safe(['name']));
});

上から順に、dd() の結果です。

array:1 ["name" => "taro"
]

array:2 ["age" => "35"
  "hobby" => "tennis"
]

Illuminate\Support\ValidatedInput {#345 ▼
  #input: array:4 [▼
    "name" => "taro"
    "age" => "35"
    "hobby" => "tennis"
    "hoge" => "bar"
  ]
}

array:1 ["name" => "taro"
]

->only() や ->except() は、その名前の通りです。
->merge() は、任意の値を追加したい時に使えます。上記を見ると、ValidatedInput が返ってきていますので、メソッドチェーンで更に ->only() とか繋げられます。
最後の ->safe(['name'])) は、ドキュメントには載っていませんが、->safe() に直接配列を渡すと、->only() を呼び出したのと同じ結果になります。

(追記 2021-11-13 時点)
FormRequestの場合を除き、コントローラーなどで自ら validator を作成する場合は、validate() やら fails() など使って適切に処理してから、safe() を呼び出します。さもないと正しくバリデーションされません。

まとめ

なかなか便利そうですね。

間違い等見つけましたらコメント下さい。

Discussion