今回は、知っていたけれどあまり使っていない、ことの話です。Laravelの入力バリデーションのことなのですが、忘れずに書いておいてより使うようにしたいです。

Laravelの入力のバリデーションでは複数のルールがあると、それらルールすべてが適用されます。

例えば、入力項目は年齢で、ルールは入力値は数字(整数)であり、かつ10歳以上とします。

$php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.16 — cli) by Justin Hileman
>>> $input = ['age' => '9'];
=> [
     "age" => "9",
   ]
>>> $rule = ['age' => 'integer|gte:10'];
=> [
     "age" => "integer|gte:10",
   ]
>>> validator($input, $rule)->errors()->all();
=> [
     "The age must be greater than or equal 10.",
   ]

入力値が9歳なら、上のようにエラーとなります。エラーは配列で返ります。

さて、ここで入力値を、数字でなく英字としてみます。

>>> $input = ['age' => 'abc'];
=> [
     "age" => "9",
   ]
>>> $rule = ['age' => 'integer|gte:10'];
=> [
     "age" => "integer|gte:10",
   ]
>>> validator($input, $rule)->errors()->all();
=> [
     "The age must be an integer.",
     "The age must be greater than or equal 10.",
   ]

あれ、と思うのは最初の数字のルールで、ルールの適用が止まらないことです。これはLaravelの作者によると、すべてのルールの結果を見せたい、という仕様らしい。

しかし、最初のエラーだけを画面に表示するのは大半のケースです。さらに、例ば、ルールにおいて、2番目のルールがDBのチェックを必要すると、1番目のルールに通らなかったら、わざわざ時間がかかる2番目のDBのクエリの実行は必要はありません。

そういう場合は、bailをルールの最初に置くと、

>>> $rule = ['age' => 'bail|integer|gte:10'];
=> [
     "age" => "bail|integer|gte:10",
   ]
>>> validator($input, $rule)->errors()->all();
=> [
     "The age must be an integer.",
   ]

2番目のルールは実行されません。

このbailの登場は、5.6からのようですが、最新の5.5でも対応しています。

By khino