根本原因是控制器未调用withInput()或调用时机错误,导致session的flash区域无数据,old()函数自然返回空。

old() 函数读不到数据,是因为 session 里压根没存进去
根本原因不是 old() 有问题,而是控制器没调用 withInput(),或者调用时机不对。Laravel 的 old() 只是从 session 的 flash 区域读数据,如果那里是空的,它自然返回 null 或空字符串。
常见错误场景:
- 手动验证时忘了加
->withErrors($validator)->withInput() - 用了 Form Request,但没在控制器里 return 重定向响应(比如写了
if ($request->fails()) { ... }却没 return) - 验证失败后直接
return view(...)而非redirect()->back()或带withInput()的重定向 - 在中间件或全局异常处理器里吞掉了验证失败的重定向(比如自定义了
Handler.php却没调用父类的render())
Form Request 验证失败时 old() 失效的典型配置遗漏
Form Request 类本身会自动触发重定向和 withInput(),但前提是它被正确注入到控制器方法中,并且没被绕过。
容易被忽略的三点:
- 控制器方法参数类型必须是你的 Form Request 类,不能是
Request或Illuminate\Http\Request,否则 Laravel 不会自动执行验证流程 -
authorize()方法返回false会导致请求被中断为 403,跳过验证和withInput(),此时old()也读不到任何东西 - 若在
rules()里引用了动态字段(如'profile.' . $this->input('type') . '.url'),而该字段在原始请求中不存在,withInput()可能只存了部分键,导致某些old('profile.xxx')返回空
Session 驱动或配置导致 old() 数据“消失”
即使控制器正确调用了 withInput(),old() 仍可能返回空——问题出在 session 生命周期或存储后端。
检查这些点:
- 开发环境用了
filesession 驱动,但storage/framework/sessions目录权限不对,写入失败 - 生产环境用了
redis或database驱动,但连接配置错误或超时,导致 flash 数据未落库 -
SESSION_LIFETIME设得太小(如 1 分钟),用户填表时间稍长,session 已过期 - 启用了
SameSite=Lax或Strict的 cookie 策略,而表单是跨域提交(如前端 Vue SPA 调后端 Laravel API),浏览器不带 session cookie,导致服务端无法关联旧输入
Blade 模板里 old() 写法错误或被覆盖
old() 是函数调用,不是变量,写错括号或参数名就拿不到值。
高频误写:
-
{{ old('email') }}写成{{ old email }}(漏括号)或{{ old['email'] }}(当数组用) - 字段名大小写不一致:表单
<input name="user_email">,却写{{ old('User_Email') }} - 嵌套字段用了点号但没加引号:
{{ old('address.city') }}正确,{{ old(address.city) }}会报 PHP 解析错误 - 在表单外提前调用了
old()(比如在<head>里),导致 flash 数据被提前消费(Laravel 的 flash 机制是“读即销毁”,第二次调用同 key 就为空)
最隐蔽的问题:模板里混用了 $errors->has('field') 和 old('field'),但 $errors 来自 session flash,old() 也来自同一处;如果某处代码手动清空了 session(如 session()->forget('_old_input')),两者都会失效。


















