我必须验证API的输入字段,其值必须是1到100之间的整数或null
,否则甚至不设置(不是必需的)。
因此,我的验证规则是:'privacy_status' => "nullable|integer|min:1|max:100",
这个工作正常,直到我得到一个空字符串作为值。由于Laravel对空字符串的验证仅在字段隐式时才会验证,因此忽略所有其他规则integer, nullable or min, max
。
protected function isValidatable($rule, $attribute, $value)
{
return $this->presentOrRuleIsImplicit($rule, $attribute, $value) &&
$this->passesOptionalCheck($attribute) &&
$this->isNotNullIfMarkedAsNullable($attribute, $value) &&
$this->hasNotFailedPreviousRuleIfPresenceRule($rule, $attribute);
}
protected function presentOrRuleIsImplicit($rule, $attribute, $value)
{
if (is_string($value) && trim($value) === '') {
return $this->isImplicit($rule);
}
return $this->validatePresent($attribute, $value) || $this->isImplicit($rule);
}
有没有办法正确验证?
答案 0 :(得分:1)
修改强>
您始终可以创建自定义验证规则。
Validator::extendImplicit('fail_on_empty_string', function($attribute, $value, $parameters)
{
return $value === "" ? false : $value;
});
您可以使用以下新规则:
'privacy_status' => "fail_on_empty_string|nullable|integer|min:1|max:100",
旧答案
这在Laravel文档中有描述,是你自己介绍的一个错误(虽然可能是无意识的):https://laravel.com/docs/5.6/validation#a-note-on-optional-fields:
默认情况下,Laravel在应用程序的全局中间件堆栈中包含TrimStrings和ConvertEmptyStringsToNull中间件。这些中间件由App \ Http \ Kernel类列在堆栈中。因此,如果您不希望验证程序将空值视为无效,则通常需要将“可选”请求字段标记为可为空。
空字符串会自动转换为null,您的验证完全没问题。禁用中间件,更改它或更改验证规则。
答案 1 :(得分:0)
您只需将filled规则传递给它即可。这将允许该字段可以为空,如果它存在于请求中;它不能是空的。
'privacy_policy' => 'filled|integer|min:1|max:100'
如果您希望在present时允许空字符串,请改为显示当前规则。
'privacy_policy' => 'present|nullable|integer|min:1|max:100'
我添加了一个单元测试来证明这是正常的。
public function index()
{
request()->validate([
'privacy_policy' => 'filled|integer|min:1|max:100'
]);
return response();
}
然后在测试中:
$this->get(route('test'))->assertStatus(200); // True
$this->get(route('test'), ['privacy_policy' => ''])->assertStatus(200); // False
$this->get(route('test'), ['privacy_policy' => 5])->assertStatus(200); // True