You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel日期字段输入非法文本存1970-01-01,如何正确校验并提示错误?

问题根源
  1. 逻辑顺序错误:你提前在控制器把用户输入转成Y-m-d格式后才执行校验,strtotime()处理非法字符串时会返回false,date("Y-m-d", false)会直接生成1970-01-01,这个值符合你设置的date_format:Y-m-d校验规则,所以不会触发格式报错。
  2. 校验规则不匹配:用户实际输入的是d/m/Y格式的日期,你却针对转换后的Y-m-d做校验,完全没有对用户原始输入做合法性校验。
  3. 转换逻辑无有效性判断:没有判断strtotime()的返回值是否合法,直接把转换后的错误日期写入请求参数。
修复方案

步骤1:调整校验规则,直接校验用户原始输入

把校验规则改为针对用户输入的d/m/Y格式做校验,不要提前转换日期,非法格式会直接在这一步触发报错:

'date_of_birth' => [
    'required',
    'bail',
    // 直接校验用户输入的格式为d/m/Y,非法内容直接抛出格式错误
    'date_format:d/m/Y',
    function ($attribute, $value, $fail) {
        // 前面已经校验过格式,这里转换不会报错
        $birthDate = \Carbon\Carbon::createFromFormat('d/m/Y', $value);
        $age = $birthDate->age;
        if ($age < 18 || $age > 70) {
            $fail('Âge invalide. l\'âge devrait être 18-70');
        }
    }
]

校验阶段不需要手动修改请求参数的格式,Laravel校验失败后会自动返回用户原始输入用于表单回显,不需要你手动转格式再merge回请求。

步骤2:校验通过后再做格式转换,加有效性判断

控制器里只有校验通过后才执行日期转换,加一层时间戳有效性判断做兜底:

if (!empty($request->date_of_birth)) {
    $date = str_replace('/', '-', $request->date_of_birth);
    $timestamp = strtotime($date);
    // 只有时间戳有效时才做转换
    if ($timestamp !== false) {
        $new_bday = date("Y-m-d", $timestamp);
        $request->merge(['date_of_birth' => $new_bday]);
    } else {
        // 兜底逻辑,极端情况未被校验拦住时返回错误
        return back()->withErrors(['date_of_birth' => '日期格式无效,请输入正确的生日'])->withInput();
    }
}

内容的提问来源于stack exchange,提问作者Volka Dimitrev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 22:15:05