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

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

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

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

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

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

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

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

由于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规则

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

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

3年前 评论

如果是任意值都能通过,那又有问题了: 对于规则
‘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啥条件会中断验证链)

3年前 评论

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

3年前 评论

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

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

3年前 评论

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

3年前 评论

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

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

3年前 评论

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

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

由于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规则

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

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!