Laravel 8.55~ やや存在感薄めの safe メソッドで遊んでみる
はじめに
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