バリデーション言語ファイルを編集するときにお気づきと思いますが、Laravel標準バリデーション Max と Min は(他に Size、Between も)調査対象の属性の型でその挙動を変えます。
'max' => [
'numeric' => ':attributeの値が:maxを超えています',
'file' => ':attributeのサイズが:max kBを超えています',
'string' => ':attributeの文字数が:maxを超えています',
'array' => ':attributeの個数が:maxを超えています',
],
'min' => [
'numeric' => ':attributeの値が:minに足りません',
'file' => ':attributeのサイズが:min kBに足りません',
'string' => ':attributeの文字数が:minに足りません',
'array' => ':attributeの個数が:minに足りません',
],
ここで問題となるのは、文字列型が入力した文字数カウントとの比較になることです。文字列比較の大小によるバリデーションは存在してません。
例えば日付型の属性に対する開始日のつもりで Min を指定しても、文字数判定となり、期待したバリデーションにはなりません。
'date_start' => 'date|min:'.date('Y-m-d'), // 開始日判定にはならない
日付の最大値と最小値
日付型の属性の前後関係の判定には、専用の after と before が用意されています。
しかも、引数の文字列は strtotime で処理されるので次のような指定が可能です。
'date_start' => 'date|after:today', // 今日より大(明日以降) 'date_end' => 'date|befor:+1 year', // 1年以内
または属性名を引数に持つことができるので、期間指定のバリデーションに使うことが出来ます。
'date_end' => 'datetime|after:date_start',

ただし、after, befor の比較は等号を含みませんので注意が必要です。
数値型のカスタムバリデーション
例えば1以上の整数(自然数)を判定するカスタムバリデーション natural_number を作成した場合、それを min や max で大小判定したときは、正しく数値として判定されるでしょうか?
結論を言えば、カスタムバリデーション natural_number は(そのままでは)、入力された値が数値であっても、文字列として判断され、文字数でカウントされてしまいます。
'quantity' => 'requied|natural_number|max:10', // 10桁( 10億)まで可
では、数値として認められるにはどのようにしたら良いのでしょうか。
vender の Validation.php でコードを追うと、getSize() メソッドにおいて次のように型判定されていることがわかります。
| 1 | 入力値が数値(is_numeric)でバリデーションに numeric か integer があれば、その値を返す |
|---|---|
| 2 | 入力値が配列(is_array)なら配列の個数を返す |
| 3 | 入力値が File インスタンスならファイルサイズを kB で返す |
| 4 | それ以外は文字数(mb_strlen)を返す |
数値として判定されるには、入力された値が数値であるかどうかだけでなく、バリデーションに numeric か integer が含まれなければなりません。これでは他のどんなルールであっても数値と判定されることはないのです。
numericRules
この数値と判断されるためのバリデーションルールは、変数 $numericRules で定義されていました。
protected $numericRules = ['Numeric', 'Integer'];
カスタムバリデーションとして数値型のルールを自作した場合には、これにルール名を追加すればよいわけです。
変数 $numericRules を protected で再定義して上書きするか、コンストラクタで必要分だけ追加します。……再定義する場合は Numeric と Integer を忘れずに。
public function __construct($translator, $data, $rules, $messages = [])
{
parent::__construct($translator, $data, $rules, $messages);
$this->numericRules[] = 'NatrualNumber';
}
/**
* 自然数 natural_number
*
* @param string $attribute 検査する属性名
* @param string $value 検査する値
* @return bool
*/
public function validateNaturalNumber($attribute, $value)
{
if ($this->validateInteger($attribute, $value))
{
return ($value > 0);
}
return false;
}
メルマガ購読の申し込みはこちらから。
