表单验证 nullable 规则,为什么' ‘几个空格字符串也能通过验证?

表单:
password = ‘’
password = ‘ ‘ (5 个空格)

都可以通过 nullable 规则,这是为啥呢? 文档里只写的是允许 null .
空字符串’’ == null 可以理解,
‘ ‘5 个空格 (帖子显示问题,只看到 1 个空格) 字符串也等于 null? 显然不对。

那就只能是文档 nullable 规则描述有误或有缺失(不全面)

难道要描述为: 允许值为 null 或空格字符串(不是空字符串)

初学 laravel,看不懂源码,求大拿把这个验证规则的源码贴一下看看,或讲讲这块是啥情况。

另外:只有表单字段名为: password 时,才不会 trim 去除空格,才有此问题。 其他名称的字段,因为默认有 trim 这个中间件的缘故,多个空格字符串,就转为 null 啦,不影响。

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

由于 password 和 password_confirmation 字段不会被 \App\Http\Middleware\TrimStrings::class 中间件 trim 掉,但是在验证字段规则时,Illuminate\Validation\Validator 类的 validateAttribute 方法会先调用 isValidatable 方法来判断一组【属性、规则、属性值】是否是可验证的,isValidatable 里面会调用 presentOrRuleIsImplicit 判断值是否是存在的,或者规则是否是隐式规则:if (is_string($value) && trim($value) === '') { return $this->isImplicit($rule); }
被 trim 后的 value 当然不符合这个条件,因此其实是 laravel 认为你这个全是空格的字符串是不存在的,跳过了验证步骤。解决方案:1. 前端不允许密码出现空格,从 TrimStrings 的 expect 数组中移除 password 和 password_confirmation 字段,2. 验证规则里面加上 required 规则

4年前 评论
wpcolor (楼主) 4年前
讨论数量: 8
Epona

nullable 的意思是这个字段可以为空(nullable 的字面意思)。 意思是你有没有这个字段,字段是任何值 都能通过校验(和没校验一样

4年前 评论

如果是任意值都能通过,那又有问题了: 对于规则
‘password’ => ‘nullable|string|between:6,30|confirmed’,
本意是想,如果客户提供了 password 值,就更新密码,否则保持原样。

1,当 password 值为 123 时,会走 nullable 后面的规则验证,返回不在允许的范围并验证 2 次输入是否一致。即 password 正常验证。
2,当不传 password 值是,直接是 null,走 nullable 验证,直接中断不进行后面的规则验证。也就是说 nullable 中断了,不会验证后面 n 多规则。

这样看起来,nullable 应该理解为,值等于 null 时,就直接中断,否则继续后面的规则。

然而:
重点:但当 password=’’ 5 个空格时(5 个空格应该不等于 null 吧?)并没有当做有 5 个空格的值去验证后面的规则,而是被 nullable 中断了(也就是说,在 nullable 规则看来,5 个空格 ==null ?),此时在控制器获取通过验证的数据,打印 password,就是一个包含 5 个空格的字符串!(因为 password 特殊名称,trim 中间件默认不去除空格)

疑问?
1,nullable 什么条件会中断验证?
2,我怀疑:nullable 验证时,会类似调用 trim 去除空格,这样 n 个空格的字符串,也都等于 null 了,然后就通过验证,并中断验证。(当然前提还是知道 nullable 啥条件会中断验证链)

4年前 评论

看这个 sometimes,nullable 永远都通过的,不会中断。

4年前 评论

我真的服了 password 这个名称了。 ['mm' => [function ($attr, $value, $fail) { $fail ($attr . ' 的值 ' . $value . ' 不被接受 '); } ], ],

就这个规则,你用名称: mm ,输入 5 个空格,就会报错,执行你的验证函数。 但,当你用名称 password 时,输入 123 还能执行这个验证函数,但输入 5 个空格,压根就不执行这个验证函数。
password 名称,到底是个什么神奇的存在啊,这把人弄的晕的

4年前 评论

@widdy 不是的,我实测是会中断,上面不都给出规则和代码实例了么,就是不执行后面的规则,就是中断 @Epona 感觉 password 是个特殊性的东西,和一般预期不一样,请看我自定义函数那个回复

4年前 评论

越来越晕,本来还以为快弄清楚这个简单问题了,结果越测试,越不明白。

现在的问题又追加 1 个: 当表单字段名称为 password 时,输入 5 个空格,为啥压根都不执行验证了

4年前 评论

@widdy 可能有点误会,你说的中断,是指是否能通过 nullable 测试吧?我说的中断,是指在一串验证规则时, 比如:‘nullable|string|between:6,30|confirmed’ ,不会执行后面的 string,between 这些验证规则

4年前 评论
风吹过有夏天的味道 4年前
widdy 4年前
风吹过有夏天的味道 4年前
widdy 4年前

由于 password 和 password_confirmation 字段不会被 \App\Http\Middleware\TrimStrings::class 中间件 trim 掉,但是在验证字段规则时,Illuminate\Validation\Validator 类的 validateAttribute 方法会先调用 isValidatable 方法来判断一组【属性、规则、属性值】是否是可验证的,isValidatable 里面会调用 presentOrRuleIsImplicit 判断值是否是存在的,或者规则是否是隐式规则:if (is_string($value) && trim($value) === '') { return $this->isImplicit($rule); }
被 trim 后的 value 当然不符合这个条件,因此其实是 laravel 认为你这个全是空格的字符串是不存在的,跳过了验证步骤。解决方案:1. 前端不允许密码出现空格,从 TrimStrings 的 expect 数组中移除 password 和 password_confirmation 字段,2. 验证规则里面加上 required 规则

4年前 评论
wpcolor (楼主) 4年前