FormRequest需满足三条件才生效:控制器参数类型提示为具体类、authorize()返回true、不手动调用validate();required_if/required_unless严格匹配类型和空格;错误消息键名须为“字段名.规则名”;prepareForValidation()用于验证前数据预处理。

FormRequest 类不是“写完就能用”的验证工具,它必须被正确接入请求流程才能生效。核心在于类型提示、授权控制和生命周期钩子的协同使用——漏掉任意一环,规则就可能完全不触发。
为什么 rules() 总是不生效
最常见原因是 Laravel 根本没执行你的 FormRequest。它不会自动运行,必须满足三个条件:
- 控制器方法参数要明确写成 StorePostRequest $request,不能是 Request 或父类 FormRequest
- authorize() 方法必须返回 true;默认实现就是 return false,会直接拦截为 403
- 不能手动调用 $request->validate() —— 这会跳过 prepareForValidation()、withValidator() 等全部钩子
required_if 和 required_unless 的实际坑点
这两个规则对值的匹配非常严格,容易因前后端数据类型不一致而失效:
- 前端传的是字符串 "true",但规则写成 required_if:is_paid,true 就会失败;应改用 required_if:is_paid,1 或 Laravel 9+ 的 required_if:is_paid,==,1
- 字段带空格(如 " active ")会导致 required_if:status,active 不命中,务必搭配 trim 规则:'status' => 'required|trim|string'
- 避免与 nullable 或 sometimes 混用在同一字段,nullable 会让 required_if 完全失效
自定义错误消息只显示一半?键名格式错了
错误消息绑定靠的是精确的“字段名.规则名”结构,错一个字符就不认:
- 正确写法:'email.required' => '邮箱不能为空'
- 错误写法:'required' => '不能为空' —— 这会覆盖所有字段的 required 提示
- 嵌套字段如 photos.*.url,错误键也得保持一致:'photos.*.url.url' => '图片链接格式不合法'
预处理数据:prepareForValidation() 是关键入口
有些字段需要清洗或补全后才能验证,比如把空字符串转 null、合并多个字段、添加默认值。这些逻辑不该塞进控制器,也不该靠前端传:
- prepareForValidation() 在验证前自动触发,接收一个引用参数 &$data
- 可直接修改 $data,例如:$data['price'] = $data['price'] ?? 0;
- 也可做类型转换:$data['is_active'] = filter_var($data['is_active'], FILTER_VALIDATE_BOOLEAN);


















