Files
mpay_v2_webman/doc/validation.md
2026-03-10 13:47:28 +08:00

11 KiB
Raw Blame History

验证器 webman/validation 基于 illuminate/validation提供手动验证、注解验证、参数级验证以及可复用的规则集。

安装 composer require webman/validation 基本概念 规则集复用:通过继承 support\validation\Validator 定义可复用的 rules messages attributes scenes可在手动与注解中复用。 方法级注解Attribute验证使用 PHP 8 属性注解 #[Validate] 绑定控制器方法。 参数级注解Attribute验证使用 PHP 8 属性注解 #[Param] 绑定控制器方法参数。 异常处理:验证失败抛出 support\validation\ValidationException异常类可通过配置自定义 数据库验证:如果涉及数据库验证,需要安装 composer require webman/database 手动验证 基本用法 use support\validation\Validator;

$data = ['email' => 'user@example.com'];

Validator::make($data, [ 'email' => 'required|email', ])->validate(); 提示 validate() 校验失败会抛出 support\validation\ValidationException。如果你不希望抛异常请使用下方的 fails() 写法获取错误信息。

自定义 messages 与 attributes use support\validation\Validator;

$data = ['contact' => 'user@example.com'];

Validator::make( $data, ['contact' => 'required|email'], ['contact.email' => '邮箱格式不正确'], ['contact' => '邮箱'] )->validate(); 不抛异常并获取错误信息 如果你不希望抛异常,可以使用 fails() 判断,并通过 errors()(返回 MessageBag获取错误信息

use support\validation\Validator;

$data = ['email' => 'bad-email'];

$validator = Validator::make($data, [ 'email' => 'required|email', ]);

if ($validator->fails()) { $firstError = $validator->errors()->first(); // string $allErrors = $validator->errors()->all(); // array $errorsByField = $validator->errors()->toArray(); // array // 处理错误... } 规则集复用(自定义 Validator namespace app\validation;

use support\validation\Validator;

class UserValidator extends Validator { protected array $rules = [ 'id' => 'required|integer|min:1', 'name' => 'required|string|min:2|max:20', 'email' => 'required|email', ];

protected array $messages = [
    'name.required' => '姓名必填',
    'email.required' => '邮箱必填',
    'email.email' => '邮箱格式不正确',
];

protected array $attributes = [
    'name' => '姓名',
    'email' => '邮箱',
];

} 手动验证复用 use app\validation\UserValidator;

UserValidator::make($data)->validate(); 使用 scenes可选 scenes 是可选能力,只有在你调用 withScene(...) 时,才会按场景只验证部分字段。

namespace app\validation;

use support\validation\Validator;

class UserValidator extends Validator { protected array $rules = [ 'id' => 'required|integer|min:1', 'name' => 'required|string|min:2|max:20', 'email' => 'required|email', ];

protected array $scenes = [
    'create' => ['name', 'email'],
    'update' => ['id', 'name', 'email'],
];

} use app\validation\UserValidator;

// 不指定场景 -> 验证全部规则 UserValidator::make($data)->validate();

// 指定场景 -> 只验证该场景包含的字段 UserValidator::make($data)->withScene('create')->validate(); 注解验证(方法级) 直接规则 use support\Request; use support\validation\annotation\Validate;

class AuthController { #[Validate( rules: [ 'email' => 'required|email', 'password' => 'required|string|min:6', ], messages: [ 'email.required' => '邮箱必填', 'password.required' => '密码必填', ], attributes: [ 'email' => '邮箱', 'password' => '密码', ] )] public function login(Request $request) { return json(['code' => 0, 'msg' => 'ok']); } } 复用规则集 use app\validation\UserValidator; use support\Request; use support\validation\annotation\Validate;

class UserController { #[Validate(validator: UserValidator::class, scene: 'create')] public function create(Request $request) { return json(['code' => 0, 'msg' => 'ok']); } } 多重验证叠加 use support\validation\annotation\Validate;

class UserController { #[Validate(rules: ['email' => 'required|email'])] #[Validate(rules: ['token' => 'required|string'])] public function send() { return json(['code' => 0, 'msg' => 'ok']); } } 验证数据来源 use support\validation\annotation\Validate;

class UserController { #[Validate( rules: ['email' => 'required|email'], in: ['query', 'body', 'path'] )] public function send() { return json(['code' => 0, 'msg' => 'ok']); } } 通过in参数来指定数据来源其中

query http请求的query参数取自 $request->get() body http请求的包体取自 $request->post() path http请求的路径参数取自 $request->route->param() in可为字符串或数组为数组时按顺序合并后者覆盖前者。未传递in时默认等效于 ['query', 'body', 'path']。

参数级验证Param 基本用法 use support\validation\annotation\Param;

class MailController { public function send( #[Param(rules: 'required|email')] string $from, #[Param(rules: 'required|email')] string $to, #[Param(rules: 'required|string|min:1|max:500')] string $content ) { return json(['code' => 0, 'msg' => 'ok']); } } 验证数据来源 类似的参数级也支持in参数指定来源

use support\validation\annotation\Param;

class MailController { public function send( #[Param(rules: 'required|email', in: ['body'])] string $from ) { return json(['code' => 0, 'msg' => 'ok']); } } rules 支持字符串或数组 use support\validation\annotation\Param;

class MailController { public function send( #[Param(rules: ['required', 'email'])] string $from ) { return json(['code' => 0, 'msg' => 'ok']); } } 自定义 messages / attribute use support\validation\annotation\Param;

class UserController { public function updateEmail( #[Param( rules: 'required|email', messages: ['email.email' => '邮箱格式不正确'], attribute: '邮箱' )] string $email ) { return json(['code' => 0, 'msg' => 'ok']); } } 规则常量复用 final class ParamRules { public const EMAIL = ['required', 'email']; }

class UserController { public function send( #[Param(rules: ParamRules::EMAIL)] string $email ) { return json(['code' => 0, 'msg' => 'ok']); } } 方法级 + 参数级混合 use support\Request; use support\validation\annotation\Param; use support\validation\annotation\Validate;

class UserController { #[Validate(rules: ['token' => 'required|string'])] public function send( Request $request, #[Param(rules: 'required|email')] string $from, #[Param(rules: 'required|integer')] int $id ) { return json(['code' => 0, 'msg' => 'ok']); } } 自动规则推导(基于参数签名) 当方法上使用 #[Validate],或该方法的任意参数使用了 #[Param] 时,本组件会根据方法参数签名自动推导并补全基础验证规则,再与已有规则合并后执行验证。

示例:#[Validate] 等价展开

  1. 只开启 #[Validate],不手写规则:

use support\validation\annotation\Validate;

class DemoController { #[Validate] public function create(string $content, int $uid) { } } 等价于:

use support\validation\annotation\Validate;

class DemoController { #[Validate(rules: [ 'content' => 'required|string', 'uid' => 'required|integer', ])] public function create(string $content, int $uid) { } } 2) 只写了部分规则,其余由参数签名补全:

use support\validation\annotation\Validate;

class DemoController { #[Validate(rules: [ 'content' => 'min:2', ])] public function create(string $content, int $uid) { } } 等价于:

use support\validation\annotation\Validate;

class DemoController { #[Validate(rules: [ 'content' => 'required|string|min:2', 'uid' => 'required|integer', ])] public function create(string $content, int $uid) { } } 3) 默认值/可空类型:

use support\validation\annotation\Validate;

class DemoController { #[Validate] public function create(string $content = '默认值', ?int $uid = null) { } } 等价于:

use support\validation\annotation\Validate;

class DemoController { #[Validate(rules: [ 'content' => 'string', 'uid' => 'integer|nullable', ])] public function create(string $content = '默认值', ?int $uid = null) { } } 异常处理 默认异常 验证失败默认抛出 support\validation\ValidationException继承 Webman\Exception\BusinessException不会记录错误日志。

默认响应行为由 BusinessException::render() 处理:

普通请求:返回字符串消息,例如 token 为必填项。 JSON 请求:返回 JSON 响应,例如 {"code": 422, "msg": "token 为必填项。", "data":....} 通过自定义异常修改处理方式 全局配置config/plugin/webman/validation/app.php 的 exception 多语言支持 组件内置中英文语言包,并支持项目覆盖。加载顺序:

项目语言包 resource/translations/{locale}/validation.php 组件内置 vendor/webman/validation/resources/lang/{locale}/validation.php Illuminate 内置英文(兜底) 提示 webman默认语言由 config/translation.php 配置,也可以通过函数 locale('en'); 更改。

本地覆盖示例 resource/translations/zh_CN/validation.php

return [ 'email' => ':attribute 不是有效的邮件格式。', ]; 中间件自动加载 组件安装后会通过 config/plugin/webman/validation/middleware.php 自动加载验证中间件,无需手动注册。

命令行生成注解 使用命令 make:validator 生成验证器类(默认生成到 app/validation 目录)。

提示 需要安装 composer require webman/console

基础用法 生成空模板 php webman make:validator UserValidator 覆盖已存在文件 php webman make:validator UserValidator --force php webman make:validator UserValidator -f 从表结构生成规则 指定表名生成基础规则(会根据字段类型/可空/长度等推导 $rules默认排除字段与 ORM 相关laravel 为 created_at/updated_at/deleted_atthinkorm 为 create_time/update_time/delete_time php webman make:validator UserValidator --table=wa_users php webman make:validator UserValidator -t wa_users 指定数据库连接(多连接场景) php webman make:validator UserValidator --table=wa_users --database=mysql php webman make:validator UserValidator -t wa_users -d mysql 场景scenes 生成 CRUD 场景create/update/delete/detail php webman make:validator UserValidator --table=wa_users --scenes=crud php webman make:validator UserValidator -t wa_users -s crud update 场景会包含主键字段用于定位记录以及其余字段delete/detail 默认仅包含主键字段。