Laravelの「integer」ルールのバリデーション
概要
LaravelのValidationルールで「integer」があるが、これは型までチェックしているのか?と思ったのが調べるきっかけ。
どういうことかというと、
'id' => 'required|integer',
と書いていたバリデーションルールに対して、string型での数値が通っていた。
LaravelにおけるValidationの流れ
そもそもの話
ざっくり書くとControllerでこのようにValidationを実行しているが、
use ValidatesRequests; $this->validate($request, $this->validator->getRules(), $this->validator->getMessage(), $this->validator->getAttribute());
このときの処理の流れは、
①
vendor\laravel\framework\src\Illuminate\Foundation\Validation\ValidatesRequests.php: validate()
②
vendor\laravel\framework\src\Illuminate\Validation\Validator.php: validate()
③
vendor\laravel\framework\src\Illuminate\Validation\Validator.php: fails()
④
vendor\laravel\framework\src\Illuminate\Validation\Validator.php: passes()
⑤
vendor\laravel\framework\src\Illuminate\Validation\Validator.php: validateAttribute()
Validationの実体
validateAttributeの中身がこんな感じ
/** * Validate a given attribute against a rule. * * @param string $attribute * @param string $rule * @return void */ protected function validateAttribute($attribute, $rule) { $this->currentRule = $rule; list($rule, $parameters) = ValidationRuleParser::parse($rule); if ($rule == '') { return; } // First we will get the correct keys for the given attribute in case the field is nested in // an array. Then we determine if the given rule accepts other field names as parameters. // If so, we will replace any asterisks found in the parameters with the correct keys. if (($keys = $this->getExplicitKeys($attribute)) && $this->dependsOnOtherFields($rule)) { $parameters = $this->replaceAsterisksInParameters($parameters, $keys); } $value = $this->getValue($attribute); // If the attribute is a file, we will verify that the file upload was actually successful // and if it wasn't we will add a failure for the attribute. Files may not successfully // upload if they are too large based on PHP's settings so we will bail in this case. if ($value instanceof UploadedFile && ! $value->isValid() && $this->hasRule($attribute, array_merge($this->fileRules, $this->implicitRules)) ) { return $this->addFailure($attribute, 'uploaded', []); } // If we have made it this far we will make sure the attribute is validatable and if it is // we will call the validation method with the attribute. If a method returns false the // attribute is invalid and we will add a failure message for this failing attribute. $validatable = $this->isValidatable($rule, $attribute, $value); if ($rule instanceof RuleContract) { return $validatable ? $this->validateUsingCustomRule($attribute, $value, $rule) : null; } $method = "validate{$rule}"; if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) { $this->addFailure($attribute, $rule, $parameters); } }
これを見ると、integer
の場合、validateInteger
でvalidationが実行されそう。
なので追ってみた。
$method = "validate{$rule}"; if ($validatable && ! $this->$method($attribute, $value, $parameters, $this)) { $this->addFailure($attribute, $rule, $parameters); }
/** * Validate that an attribute is an integer. * * @param string $attribute * @param mixed $value * @return bool */ public function validateInteger($attribute, $value) { return filter_var($value, FILTER_VALIDATE_INT) !== false; }
ということで、結局は filter_var($value, FILTER_VALIDATE_INT)
FILTER_VALIDATE_INTを調べた
とりあえず読んでみた
It's good to remember that using filter_var is primarily for filtering input values when doing boolean logic comparisons. Take the following: $value = "12"; if(filter_var($value, FILTER_VALIDATE_INT)) { // validated as an int }
これを読むと Stringっぽくクォートで囲った値を送っても、intとして処理が通りそう。
結論
型というより、整数形式の表現だったら、何でも通るのではないかと思った。
補足
1ヶ月くらい前に下書きで書いてて、公開するの忘れてたやつ。