Laravel 的验证器通过“可为空”规则传递空字符串
Posted
技术标签:
【中文标题】Laravel 的验证器通过“可为空”规则传递空字符串【英文标题】:Laravel's validator passes for empty string with 'nullable' rule 【发布时间】:2017-10-17 23:07:43 【问题描述】:例子:
Validator::make(['x' => ''], ['x' => 'nullable|integer|min:1'])->errors()->all();
输出:
[]
当x
为 null 或 1,2,3 等时,它工作正常。
当x
是除空字符串之外的其他内容时,验证器表示错误。
数据库中的列可以是 NULL 或正整数,所以当我传递空字符串时,验证器告诉我这很好,但 mysql 会抛出异常,因为它试图将 ''
(空字符串)保存在可为空的整数列中。
字段的唯一允许值是:null
、1,2,3,4,...
,其他一切都应该失败。
如果我添加 required
规则,则验证器会因 null
值('nullable|required|integer|min:1')而失败
【问题讨论】:
规则nullable
只说,该值可以是null
,但它不会将空值转换为null
本身。
该值不为空,因此nullable
在这里实际上并不有效。如果你这样做 Validator::make(['x' => ''], ['x' => 'integer|min:1'])->errors()->all();
你仍然没有错误
【参考方案1】:
Laravel 5.4 带有一个全局中间件,默认将所有空字符串转换为 null。如果您不想这样做,请从列表中注释掉中间件。
app/Http/Kernel.php
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
【讨论】:
【参考方案2】:通读源码有这个功能(在Validator.php
)
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);
函数presentOrRuleIsImplicit
基本上表示如果值为''
,则仅在规则为“隐式”时才验证它(基本上如果需要属性)。
在这种情况下,如果它既是必需的又可为空的验证将失败,因为''
与 null 不同。
Laravel 5.4 有一个名为 ConvertEmptyStringsToNull
的内置中间件,它通过获取所有 ''
值并将它们转换为 null 来帮助处理这种差异。
【讨论】:
以上是关于Laravel 的验证器通过“可为空”规则传递空字符串的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Scala 在 DataFrame 中添加新的可为空字符串列