Laravel日期校验抛出Carbon InvalidFormatException错误如何解决
问题原因
Laravel 验证规则默认会执行完指定字段的全部校验逻辑,哪怕前面的date_format:Y-m-d已经判定输入格式不符合要求,后面的自定义年龄校验闭包仍会继续执行。此时用Carbon::createFromFormat('Y-m-d', $value)解析18/12/1995这类非Y-m-d格式的字符串,就会直接抛出格式异常,无法走正常的验证错误提示流程。
修复方案
新增
bail规则终止后续校验
给date_of_birth的校验规则最前面加bail关键字,触发任意前置校验失败后直接终止后续逻辑,避免格式错误时仍执行Carbon解析代码,修正后的验证规则如下:$rules = [ 'date_of_birth'=>[ 'bail', // 验证失败即终止后续规则执行 'required', 'date', 'date_format:Y-m-d', function ($attribute, $value, $fail) { $age = Carbon::createFromFormat('Y-m-d', $value)->diff(Carbon::now())->y; if($age < 18 || $age > 70) { $fail('年龄无效,需在18-70岁之间'); } }, ] ];如果需要自定义格式错误提示,可以在验证时传入自定义消息:
$messages = [ 'date_of_birth.date_format' => '出生日期必须为年-月-日格式,例如1995-12-18', ]; $request->validate($rules, $messages);前端限制输入格式
给页面的datepicker组件指定输出格式,从输入侧避免非法格式提交,以jQuery UI Datepicker为例,初始化代码参考:$('#datepicker').datepicker({ dateFormat: 'yy-mm-dd', // 强制输出年-月-日格式 changeYear: true, yearRange: '-70:-18' // 可直接限制可选年份范围,进一步降低非法输入概率 });可选兜底优化
可以在自定义闭包内加异常捕获,哪怕后续规则调整也不会直接抛出系统异常:function ($attribute, $value, $fail) { try { $birthDate = Carbon::createFromFormat('Y-m-d', $value); } catch (\Carbon\Exceptions\InvalidFormatException $e) { $fail('出生日期格式不正确,请使用年-月-日格式'); return; } $age = $birthDate->diff(Carbon::now())->y; if($age < 18 || $age > 70) { $fail('年龄无效,需在18-70岁之间'); } }
内容的提问来源于stack exchange,提问作者Veenavi Anutthara
相关产品推荐
相关产品推荐

