记一次lumen验证validate的踩坑之旅

为解决框架与DB交互问题,将lumen框架从5.2升级到了5.6

业务中validate验证时,用到了digits_between规则

参数值以35.44为例,在5.2版本里,验证通过,并且能够过滤常见的非法参数

框架升级到5.6之后,提示数据不合法

既然是升级框架引起的问题,那么我们就从validate的digits_between实现着手进行分析:

首先,方法定义的文件发生改变

从5.2的illuminate/validation/Validator.php,5.6搬到了illuminate/validation/Concerns/ValidatesAttributes.php实现(trait)

其次,实现上有微调,区别如图

5.2先检查字段值是否是数值,然后比较字段长度

5.6使用正则匹配数字串(非数字字符取反!preg_match('/[^0-9]/', $value)),然后比较字段长度

可以看出,5.2的digits_between可以匹配小数,升级到5.6之后,只能匹配数字串

进一步分析,作者设计digits_between规则的应用场景

取两组测试数据分析:

假如取值区间定义为10.001~2000.001,期望参数值大于10.001小于2000.001

参数值为1500.1

在5.2中会提示为不合法(validateDigitsBetween的第二个条件不满足,1500.1的字符串长度为6,而下限为10.0001),不符合我们的期望

假如取值区间定义为0.001~5.001,期望参数值大于0.001小于5.001

参数值为1000,在5.2中会通过校验(满足数值,数值字符串长度为4,大于0.001,小于5),显然也不符合我们对于取值区间的定义

当然,两组数据在5.6中都不符合要求(第一个条件就验证不通过)

digits_between从设计之初就不是用来作小数匹配,而是作数字串长度匹配,validateDigitsBetween方法从5.2到5.6的升级,作者修复了参数可以是小数的BUG

我们在业务中使用digits_between来验证数值在小数区间内的方法其实存在疏漏~~~但是在5.2中一直使用digits_between的取值区间上下限值设置的比较特殊,恰好过滤掉了下限值(任何一个数值参数的字符串长度都会大于1>>0.0001),而就业务数据而言,几乎不会出现超过设置的上限值位数(亿)量级参数,直到框架升级,这个方法的实现逻辑改变,这个问题才暴露出来

最后,如何以正确的姿势使用validate验证规则来支持小数区间的匹配呢?

注意到validate还有一条between规则

在validateBetween方法里定义,该方法使用了getSize方法,进一步分析getSize

对于设置了数值类型的匹配规则,并且参数值也是数值,getSize返回参数值本身,可直接用参数值与设置的区间上下限值做比较,因此,小数区间的匹配,定义如下的validate规则即可

"quantity" => 'required|numeric|between:0.0001,999999999.9999'

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180322G0H9RB00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动