🤨

【Laravel】FormRequest::validate('key')を多用しない

2023/05/06に公開

❓FormRequest::validate()って?

FormRequestは、Laravelで認可と検証を行うクラスです。
その中でもvalidated()メソッドは、FormRequest::rules()で定義したルールにしたがって検証したフォームの内容を取得返してくれるものです。

✅ 本題

さて、Laravel9 からFormRequestvalidated()メソッドが引き数を受け取るようになってます。

FormRequest.php
    public function validated($key = null, $default = null)
    {
        return data_get($this->validator->validated(), $key, $default);
    }

Laravel8 までのvalidated()

FormRequest.php
    public function validated()
    {
        return $this->validator->validated();
    }

要は、今までキーを指定して取得する際はRequest::input()などで取得していたものを、検証済みの値であることを明確化できるようになった、と言えます。

$request->input('name'); // 検証済みなん...?

$request->validated('name'); // 検証済みなんやで!

ただ、このvalidated()の中身、$this->validator->validated()の中を見ると、このようになっていて、毎回ルールを使用してforeachを回すような仕組みになっているではありませんか
まあ、validatedなので当然っちゃあ当然ですね。

Illuminate\Contracts\Validation\Validator
    public function validated()
    {
        throw_if($this->invalid(), $this->exception, $this);

        $results = [];

        $missingValue = new stdClass;

        foreach ($this->getRules() as $key => $rules) {
            if ($this->excludeUnvalidatedArrayKeys &&
                in_array('array', $rules) &&
                ! empty(preg_grep('/^'.preg_quote($key, '/').'\.+/', array_keys($this->getRules())))) {
                continue;
            }

            $value = data_get($this->getData(), $key, $missingValue);

            if ($value !== $missingValue) {
                Arr::set($results, $key, $value);
            }
        }

        return $this->replacePlaceholders($results);
    }

ですが、つまるところそれぞれの検証済みデータを、毎回個別に取得していると、その度にルール分foreachすることになるのでは...?ってことです。

まとめ

$request->validated($key)を使うこと自体が悪なのではなく、あくまでも多用は良くなさそう、ということです。
バリデーション項目が多いフォームなどを扱うアクションでその値を使いたいときは、今まで同様一括で取得してしまった方が良いんじゃないですかね〜、という話でした。

$validated_inputs = $request->validated();

$validated_inputs['name'];
$validated_inputs['email'];
$validated_inputs['address'];

Discussion