Laravel 5.6自定义验证规则不生效,如何排查问题?
遇到自定义规则没触发、调试代码没反应的情况确实让人头疼,结合你的代码,我整理了几个最可能的原因和排查步骤:
1. 请求参数结构与验证规则不匹配
你用了嵌套数组规则 orders.*.positions.*.delivery_time,这意味着请求数据必须严格对应这个层级结构,比如:
[ 'orders' => [ [ 'positions' => [ ['delivery_time' => '2024-05-20 14:30:00'] ] ] ] ]
如果请求中的键名有误(比如写成order/position单数,或者delivery_date)、层级不对,Laravel会找不到需要验证的字段,你的自定义规则根本不会执行。
排查方法:在控制器验证代码前添加 dd($request->all()),确认请求数据的结构和键名是否完全匹配规则中的路径。
2. 自定义规则类未正确引入
如果控制器里没有正确引入CheckDeliveryDate类,Laravel会找不到这个规则,即使没有报错也需要确认:
// 确保控制器顶部有这个引入(根据你的规则类实际位置调整命名空间) use App\Rules\CheckDeliveryDate;
3. 前置验证规则拦截导致自定义规则未执行
你的规则是 'required', 'date', new CheckDeliveryDate($client_id),Laravel默认会按顺序验证,前面的规则失败后,后面的规则不会执行。不过你说$validator->fails()返回false,说明前置验证都通过了,这条可能性较低,但可以暂时移除前置规则,单独测试自定义规则是否触发。
4. 验证器实例化后的逻辑问题
确认你在调用 $validator->fails() 前没有修改过请求数据,比如有没有用 $request->only() 或者其他方法过滤掉了需要验证的字段?确保 $request->all() 确实包含了orders数组。
额外的代码优化建议
除了生效问题,你的代码还有两个小问题:
$error_messge拼写错误,应该是$error_message,否则自定义错误消息无法正确返回;- 构造函数中的
$is_after_midday变量没有被使用,可以考虑移除,或者在passes方法中利用这个变量扩展验证逻辑。
测试小技巧:暂时简化验证规则,比如改成:
public function rules($client_id) { return [ 'delivery_time' => [ 'required', 'date', new CheckDeliveryDate($client_id) ], ]; }
然后提交包含delivery_time字段的请求,看看自定义规则里的调试代码是否触发,这样可以快速排除嵌套数组的问题。
内容的提问来源于stack exchange,提问作者radar4ick

