Laravel 13 验证新特性详解

摘要

Laravel 13 对验证系统进行了增强,提供了更灵活的验证规则和错误处理。本文将深入讲解 Laravel 13 的验证新特性,包括:

  • 表单请求验证
  • 自定义验证规则
  • 条件验证
  • 错误消息定制
  • 实战案例与最佳实践

本文适合希望掌握 Laravel 13 验证新特性的开发者。

1. 表单请求验证

1.1 创建表单请求

1
php artisan make:request StorePostRequest

1.2 定义规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;

class StorePostRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}

public function rules(): array
{
return [
'title' => ['required', 'string', 'max:255'],
'content' => ['required', 'string', 'min:100'],
'status' => ['required', Rule::in(['draft', 'published'])],
'category_id' => ['required', 'exists:categories,id'],
'tags' => ['array'],
'tags.*' => ['exists:tags,id'],
];
}
}

1.3 自定义消息

1
2
3
4
5
6
7
8
public function messages(): array
{
return [
'title.required' => '标题不能为空',
'content.min' => '内容至少需要 :min 个字符',
'status.in' => '状态值无效',
];
}

1.4 属性名称

1
2
3
4
5
6
7
8
public function attributes(): array
{
return [
'title' => '标题',
'content' => '内容',
'status' => '状态',
];
}

2. 控制器验证

2.1 validate 方法

1
2
3
4
5
6
7
8
9
public function store(Request $request)
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'content' => 'required|string',
]);

// 验证通过,使用 $validated
}

2.2 validateWithBag

1
2
3
4
5
6
public function store(Request $request)
{
$validated = $request->validateWithBag('post', [
'title' => 'required|string|max:255',
]);
}

3. 自定义验证规则

3.1 创建规则

1
php artisan make:rule Uppercase

3.2 规则实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php

namespace App\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class Uppercase implements ValidationRule
{
public function validate(string $attribute, mixed $value, Closure $fail): void
{
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
}
}

3.3 使用规则

1
2
3
4
5
6
7
8
use App\Rules\Uppercase;

public function rules(): array
{
return [
'code' => ['required', new Uppercase],
];
}

3.4 闭包规则

1
2
3
4
5
6
7
8
9
10
11
12
13
public function rules(): array
{
return [
'code' => [
'required',
function ($attribute, $value, $fail) {
if (strtoupper($value) !== $value) {
$fail('The :attribute must be uppercase.');
}
},
],
];
}

4. 条件验证

4.1 sometimes 方法

1
2
3
4
5
6
7
$validator = Validator::make($request->all(), [
'title' => 'required|string|max:255',
]);

$validator->sometimes('content', 'required|string', function ($input) {
return $input->status === 'published';
});

4.2 条件规则

1
2
3
4
5
6
7
8
9
public function rules(): array
{
return [
'password' => [
'required',
Rule::when($this->isMethod('POST'), ['confirmed']),
],
];
}

4.3 排除规则

1
2
3
4
5
6
7
8
public function rules(): array
{
return [
'role' => [
Rule::prohibitedIf(fn() => !auth()->user()->isAdmin()),
],
];
}

5. 验证规则

5.1 常用规则

1
2
3
4
5
6
7
8
9
10
$rules = [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|string|min:8|confirmed',
'age' => 'required|integer|min:18|max:120',
'website' => 'nullable|url',
'avatar' => 'nullable|image|max:1024',
'date' => 'required|date|after:today',
'file' => 'required|file|mimes:pdf,doc,docx|max:10240',
];

5.2 数组验证

1
2
3
4
5
6
7
8
$rules = [
'tags' => 'array',
'tags.*' => 'string|max:50',

'users' => 'array',
'users.*.name' => 'required|string',
'users.*.email' => 'required|email',
];

5.3 文件验证

1
2
3
4
5
$rules = [
'document' => 'required|file|max:10240|mimes:pdf,doc,docx',
'image' => 'required|image|dimensions:min_width=100,min_height=200',
'video' => 'required|mimetypes:video/mp4,video/quicktime',
];

6. 错误处理

6.1 获取错误

1
2
3
4
5
6
7
8
9
10
11
12
13
// 所有错误
$errors = $validator->errors();

// 字段错误
$error = $validator->errors()->first('email');

// 所有字段错误
$allErrors = $validator->errors()->get('email');

// 检查错误
if ($validator->errors()->has('email')) {
// 有错误
}

6.2 JSON 响应

1
2
3
4
5
6
7
8
9
10
11
12
13
public function store(Request $request)
{
$validator = Validator::make($request->all(), [
'title' => 'required|string',
]);

if ($validator->fails()) {
return response()->json([
'message' => 'Validation failed',
'errors' => $validator->errors(),
], 422);
}
}

7. 实战案例

7.1 复杂验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use App\Rules\StrongPassword;

class RegisterRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}

public function rules(): array
{
return [
'name' => ['required', 'string', 'max:255'],
'email' => [
'required',
'email',
Rule::unique('users')->ignore($this->user?->id),
],
'password' => ['required', 'string', 'confirmed', new StrongPassword],
'terms' => ['required', 'accepted'],
'newsletter' => ['boolean'],
];
}

public function messages(): array
{
return [
'name.required' => '请输入您的姓名',
'email.required' => '请输入邮箱地址',
'email.email' => '请输入有效的邮箱地址',
'email.unique' => '该邮箱已被注册',
'password.required' => '请设置密码',
'password.confirmed' => '两次密码输入不一致',
'terms.accepted' => '请同意服务条款',
];
}

public function prepareForValidation(): void
{
$this->merge([
'email' => strtolower($this->email),
]);
}
}

8. 最佳实践

8.1 规则组织

1
2
3
4
5
// 推荐:数组格式
'title' => ['required', 'string', 'max:255'],

// 不推荐:字符串格式
'title' => 'required|string|max:255',

8.2 自定义消息

1
2
3
4
5
6
7
// 推荐:使用自定义消息
public function messages(): array
{
return [
'title.required' => '标题不能为空',
];
}

9. 总结

Laravel 13 的验证系统提供了强大的数据验证能力:

  1. 表单请求:封装验证逻辑
  2. 自定义规则:灵活的验证规则
  3. 条件验证:动态验证规则
  4. 错误处理:完善的错误消息

参考资料