【问题标题】:Laravel's validator passes for empty string with 'nullable' ruleLaravel 的验证器通过“可为空”规则传递空字符串
【发布时间】:2017-10-17 23:07:43
【问题描述】:

例子:

Validator::make(['x' => ''], ['x' => 'nullable|integer|min:1'])->errors()->all();

输出:

[]

x 为 null 或 1,2,3 等时,它工作正常。

x 是除空字符串之外的其他内容时,验证器表示错误。

数据库中的列可以是 NULL 或正整数,所以当我传递空字符串时,验证器告诉我这很好,但 mysql 会抛出异常,因为它试图将 ''(空字符串)保存在可为空的整数列中。

字段的唯一允许值是:null1,2,3,4,...,其他一切都应该失败。

如果我添加 required 规则,则验证器会因 null 值('nullable|required|integer|min:1')而失败

【问题讨论】:

  • 规则nullable 只说,该值可以是null,但它不会将空值转换为null 本身。
  • 该值不为空,因此nullable 在这里实际上并不有效。如果你这样做 Validator::make(['x' => ''], ['x' => 'integer|min:1'])->errors()->all(); 你仍然没有错误

标签: laravel laravel-validation


【解决方案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 来帮助处理这种差异。

    【讨论】:

      猜你喜欢
      • 2017-08-12
      • 2018-07-18
      • 2019-02-11
      • 2021-01-07
      • 1970-01-01
      • 2019-07-16
      • 2011-07-12
      • 2019-12-15
      • 1970-01-01
      相关资源
      最近更新 更多