数据验证
最后更新: 2026-01-27 11:02:47数据验证
Unicode Framework 提供了强大的数据验证系统,支持丰富的验证规则和自定义验证。
基本使用
创建验证器
use Unicode\Framework\Validation\Validator;
$data = [
'name' => 'John Doe',
'email' => 'john@example.com',
'age' => 25,
];
$rules = [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'age' => 'required|integer|min:18|max:100',
];
$validator = Validator::make($data, $rules);
if ($validator->validate()) {
// 验证通过
$validData = $validator->getValidated();
} else {
// 验证失败
$errors = $validator->errors();
}
在控制器中使用
namespace App\Index\Controller;
use Unicode\Framework\Http\Request;
use Unicode\Framework\Http\Response;
use Unicode\Framework\Validation\Validator;
class UserController
{
public function store(Request $request): Response
{
$data = $request->all();
$rules = [
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8',
];
$validator = Validator::make($data, $rules);
if (!$validator->validate()) {
return Response::json([
'errors' => $validator->errors(),
], 422);
}
// 验证通过,创建用户
$user = db('users')->insert($validator->getValidated());
return Response::json(['user' => $user], 201);
}
}
验证规则
必填规则
$rules = [
'name' => 'required', // 必填
'email' => 'required|email', // 必填且为邮箱
];
字符串规则
$rules = [
'name' => 'string', // 必须是字符串
'name' => 'string|min:3', // 字符串,最少3个字符
'name' => 'string|max:255', // 字符串,最多255个字符
'name' => 'string|min:3|max:255', // 字符串,3-255个字符
];
数字规则
$rules = [
'age' => 'integer', // 必须是整数
'age' => 'integer|min:18', // 整数,最小值18
'age' => 'integer|max:100', // 整数,最大值100
'age' => 'integer|min:18|max:100', // 整数,18-100
'price' => 'numeric', // 必须是数字(整数或小数)
'price' => 'numeric|min:0', // 数字,最小值0
];
邮箱规则
$rules = [
'email' => 'email', // 必须是有效的邮箱地址
'email' => 'required|email', // 必填且为邮箱
];
数组规则
$rules = [
'tags' => 'array', // 必须是数组
'tags' => 'array|min:1', // 数组,至少1个元素
'tags' => 'array|max:10', // 数组,最多10个元素
];
唯一性规则
$rules = [
'email' => 'unique:users,email', // 在 users 表的 email 字段中唯一
'email' => 'unique:users,email,1', // 排除 ID 为 1 的记录
'username' => 'unique:users,username', // 在 users 表的 username 字段中唯一
];
正则表达式规则
$rules = [
'phone' => 'regex:/^1[3-9]\d{9}$/', // 手机号格式
'code' => 'regex:/^[A-Z0-9]{6}$/', // 6位大写字母和数字
];
自定义规则
use Unicode\Framework\Validation\Rules\Custom;
$rules = [
'password' => [
new Custom(function($value) {
return strlen($value) >= 8 && preg_match('/[A-Z]/', $value);
}, '密码必须至少8位且包含大写字母'),
],
];
规则组合
$rules = [
'name' => 'required|string|min:3|max:255',
'email' => 'required|email|unique:users,email',
'age' => 'required|integer|min:18|max:100',
'password' => 'required|string|min:8|regex:/[A-Z]/',
'confirm_password' => 'required|string|same:password',
];
验证规则详解
required
字段必须存在且不为空。
'name' => 'required'
string
字段必须是字符串。
'name' => 'string'
integer
字段必须是整数。
'age' => 'integer'
numeric
字段必须是数字(整数或小数)。
'price' => 'numeric'
字段必须是有效的邮箱地址。
'email' => 'email'
min
字段的最小值(数字)或最小长度(字符串/数组)。
'age' => 'integer|min:18'
'name' => 'string|min:3'
'tags' => 'array|min:1'
max
字段的最大值(数字)或最大长度(字符串/数组)。
'age' => 'integer|max:100'
'name' => 'string|max:255'
'tags' => 'array|max:10'
unique
字段在数据库表中必须唯一。
// 基本用法
'email' => 'unique:users,email'
// 排除指定记录
'email' => 'unique:users,email,1' // 排除 ID 为 1 的记录
// 指定连接
'email' => 'unique:mysql2.users,email'
regex
字段必须匹配正则表达式。
'phone' => 'regex:/^1[3-9]\d{9}$/'
array
字段必须是数组。
'tags' => 'array'
Custom
自定义验证规则。
use Unicode\Framework\Validation\Rules\Custom;
$rules = [
'code' => [
new Custom(function($value) {
return $value === 'SECRET_CODE';
}, '验证码错误'),
],
];
自定义规则
创建自定义规则类
namespace App\Validation\Rules;
use Unicode\Framework\Interfaces\ValidationRuleInterface;
class PhoneNumber implements ValidationRuleInterface
{
public function validate($value, array $data = []): bool
{
return preg_match('/^1[3-9]\d{9}$/', (string) $value) === 1;
}
public function message(string $attribute): string
{
return "{$attribute} 必须是有效的手机号码";
}
}
使用自定义规则
use App\Validation\Rules\PhoneNumber;
$rules = [
'phone' => [
'required',
new PhoneNumber(),
],
];
错误处理
获取错误信息
$validator = Validator::make($data, $rules);
if (!$validator->validate()) {
// 获取所有错误
$errors = $validator->errors();
// [
// 'email' => ['邮箱格式不正确'],
// 'age' => ['年龄必须是整数'],
// ]
// 获取特定字段的错误
$emailErrors = $validator->errors('email');
// 获取第一个错误
$firstError = $validator->firstError();
}
错误消息格式
// 返回格式
[
'field_name' => [
'错误消息1',
'错误消息2',
],
]
自定义错误消息
$messages = [
'email.required' => '邮箱是必填的',
'email.email' => '邮箱格式不正确',
'age.integer' => '年龄必须是整数',
'age.min' => '年龄不能小于18岁',
];
$validator = Validator::make($data, $rules, null, $messages);
验证数据获取
获取验证后的数据
$validator = Validator::make($data, $rules);
if ($validator->validate()) {
// 获取所有验证通过的数据
$validData = $validator->getValidated();
// 只包含规则中定义的字段
// 未定义的字段会被过滤掉
}
最佳实践
1. 规则组织
// ✅ 推荐:将规则定义为常量或方法
class UserValidationRules
{
public static function create(): array
{
return [
'name' => 'required|string|min:3|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8',
];
}
public static function update(): array
{
return [
'name' => 'sometimes|string|min:3|max:255',
'email' => 'sometimes|email|unique:users,email',
];
}
}
// 使用
$rules = UserValidationRules::create();
$validator = Validator::make($data, $rules);
2. 验证时机
// ✅ 推荐:在控制器入口处验证
public function store(Request $request): Response
{
$validator = Validator::make($request->all(), $rules);
if (!$validator->validate()) {
return Response::json(['errors' => $validator->errors()], 422);
}
// 继续处理...
}
3. 错误响应格式
// ✅ 推荐:统一的错误响应格式
if (!$validator->validate()) {
return Response::json([
'success' => false,
'message' => '验证失败',
'errors' => $validator->errors(),
], 422);
}
4. 数据库验证
// ✅ 推荐:使用 unique 规则验证数据库唯一性
$rules = [
'email' => 'required|email|unique:users,email',
'username' => 'required|string|unique:users,username',
];
5. 密码验证
// ✅ 推荐:使用自定义规则验证密码强度
$rules = [
'password' => [
'required',
'string',
'min:8',
new Custom(function($value) {
return preg_match('/[A-Z]/', $value) &&
preg_match('/[a-z]/', $value) &&
preg_match('/[0-9]/', $value);
}, '密码必须包含大小写字母和数字'),
],
];
常见问题
Q: 如何验证嵌套数据?
A: 使用点号访问嵌套字段:
$data = [
'user' => [
'name' => 'John',
'email' => 'john@example.com',
],
];
$rules = [
'user.name' => 'required|string',
'user.email' => 'required|email',
];
Q: 如何验证数组中的每个元素?
A: 对数组字段应用规则:
$rules = [
'tags' => 'required|array',
'tags.*' => 'required|string|max:50', // 验证数组中的每个元素
];
Q: 如何条件验证?
A: 使用自定义规则:
$rules = [
'type' => 'required|string|in:personal,business',
'company' => [
new Custom(function($value, $data) {
if ($data['type'] === 'business') {
return !empty($value);
}
return true;
}, '企业类型必须填写公司名称'),
],
];
Q: 如何验证文件上传?
A: 文件验证需要单独处理,验证器主要用于数据验证。