更新数据库结构

This commit is contained in:
技术老胡
2026-03-10 13:47:28 +08:00
parent 54ad21ac8f
commit 9de902231f
54 changed files with 5070 additions and 501 deletions

395
doc/validation.md Normal file
View File

@@ -0,0 +1,395 @@
验证器 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 默认仅包含主键字段。