数据验证

最后更新: 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' => '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: 文件验证需要单独处理,验证器主要用于数据验证。

相关文档