laravel表单请求类需手动补全authorize()返回true和rules()定义字段规则,否则验证不触发;控制器中必须类型提示该类且作为首个参数,才能自动验证并获取validated()数据。

直接用 php artisan make:request 生成请求类,但不配置 authorize() 和 rules() 就等于没写——Laravel 表单验证不会自动触发。
怎么创建一个可用的表单请求类
运行命令生成类文件,但关键在后续两步手动补全:
- 在
authorize()方法里返回true(或按需加权限逻辑),否则所有请求直接 403 - 在
rules()方法里返回规则数组,键名必须和前端表单字段名完全一致(包括嵌套如address.street) - 类默认继承
FormRequest,无需改父类,但记得引入命名空间:use Illuminate\Foundation\Http\FormRequest;
示例:
php artisan make:request StorePostRequest
然后编辑生成的文件,确保有:
public function authorize()
{
return true; // 不是默认的 false
}
public function rules()
{
return [
'title' => 'required|string|max:255',
'content' => 'required|string',
];
}
为什么控制器里 type-hint 了却没生效
常见错误是只写了类型提示,但没把请求类当参数放在方法签名最前面,或用了错误的变量名。
- 必须作为第一个参数(或至少在路由参数之后),且不能加默认值、不能是可选参数
- 变量名无关紧要,但类型必须精确匹配类名,比如
StorePostRequest $request,不能写成Request $request - 如果控制器方法有其他依赖(如 Repository),它们得放在请求类之后
正确写法:
public function store(StorePostRequest $request)
{
// 验证已通过,直接用 $request->validated()
}
错误写法:
public function store(Request $request) // ← 这里用的是基类,不触发 FormRequest public function store($request) // ← 没类型提示,完全绕过验证 public function store(StorePostRequest $request = null) // ← 加了默认值,Laravel 不识别
自定义错误消息和字段别名怎么做
靠重写 messages() 和 attributes() 两个方法,不是改 rules() 里的字符串。
-
messages()返回键为"字段.规则" => "提示"的数组,例如'title.required' => '标题不能为空' -
attributes()返回字段映射,例如'title' => '文章标题',这样required错误会自动变成“文章标题不能为空” - 这两个方法非必需,但漏掉会导致错误信息全是英文字段名,对中文项目很不友好
示例:
public function messages()
{
return [
'content.required' => '正文内容不得为空',
];
}
public function attributes()
{
return [
'title' => '标题',
'content' => '正文',
];
}
什么时候不该用 FormRequest
不是所有验证都适合抽成请求类——它本质是「强耦合于 HTTP 请求生命周期」的工具。
- API 接口里字段动态拼接(如 JSON body 多层嵌套+运行时决定校验路径),用
Validator::make()更灵活 - 命令行任务或队列中处理数据,没有 HTTP 上下文,
FormRequest会报错或行为异常 - 简单场景(比如只校验一个 ID 是否存在),直接在控制器里用
$request->validate()更轻量
FormRequest 真正价值在于:复用性(多个控制器共用同一套规则)、可测试性(单独测请求类)、以及和 Laravel 默认错误响应格式天然对齐。但它的约束也明显:必须走 HTTP 生命周期,且一旦启用就无法跳过验证流程。











