Search by

fiberphp / validate

fiberphp

✅ FiberPHP 数据验证 —— 多规则链式验证,支持内置规则与自定义扩展。

Package info

gitee.com/fiberphp/validate.git

Issues

pkg:composer/fiberphp/validate

Statistics

Installs: 6

Dependents: 1

Suggesters: 0

dev-master 2026-09-30 10:38 UTC

This package is auto-updated.

Last update: 2026-09-30 12:52:10 UTC


README

FiberPHP 数据验证库。支持多规则链式验证、场景/分组、批量错误收集、点号与通配符多维数据访问,内置 40+ 验证规则与自定义扩展。

环境要求

  • PHP >= 8.3
  • ext-json
  • ext-mbstring
  • fiberphp/helper

安装

composer require fiberphp/validate

基本用法

use FiberPHP\Validate\Validate;

$v = new Validate();

$v->rule('name', 'require|length:2,20')
  ->rule('email', 'require|email')
  ->rule('age', 'integer|between:1,120', '年龄必须在 1-120 之间')
  ->field(['name' => '用户名', 'email' => '邮箱']);

$data = ['name' => 'tom', 'email' => 'tom@example.com', 'age' => 18];

if (!$v->check($data)) {
    echo $v->getError();   // 第一条错误(字符串)
    // $v->getError(true); // 全部错误([field => msg])
}

// 验证失败直接抛异常
$v->failException(true)->check($data);
// → throw ValidateException

取白名单数据

checked() 只返回规则中定义的字段(已通过验证):

$clean = $v->checked($_POST);   // 失败返回空数组(配合 failException 抛异常)

单值单规则

if ($v->checkRule('tom@example.com', 'email')) { /* ... */ }

// 动态方法(__call)
$v->isEmail('tom@example.com');           // → bool
$v->checkIsEmail('bad');                  // → false

规则定义

rule() 支持三种形式:

// 1. 规则串(| 分隔,参数用 : 或 , 传)
$v->rule('username', 'require|alphaDash|length:4,20');

// 2. 数组(key 为字段名)
$v->rule([
    'username|用户名' => 'require|alphaDash|length:4,20',
    'password'         => 'require|length:6,32',
]);

// 3. 闭包(返回 true/通过,false/失败,string/自定义消息)
$v->rule('mobile', function ($value) {
    return preg_match('/^1[3-9]\d{9}$/', $value) ? true : '手机号格式不符';
});

规则别名

$v->alias('pwd', 'require|length:6,32');
$v->rule('password', 'pwd');   // 等价于 require|length:6,32

类型别名映射:> → gt、>= → egt、< → lt、<= → elt、= / same → eq、<> → neq。

内置规则

类别规则
必填require / must / requireIf / requireWith / requireWithout / requireCallback / accepted / declined / acceptedIf / declinedIf
类型number / integer / float / string / boolean / array / enum(BackedEnum / UnitEnum / 常量类)
字符集alpha / alphaNum / alphaDash / chs / chsAlpha / chsAlphaNum / chsDash
网络email / mobile / url / ip / activeUrl / macAddr / allowIp / denyIp
长度/范围length / max / min / in / notIn / between / notBetween / multipleOf
比较eq / neq / gt / egt / lt / elt / confirm / different
字符串startWith / endWith / contain / regex
日期date / dateFormat / after / before / expire
文件file / image / fileSize / fileExt / fileMime

兜底:找不到对应方法时走 is(),依次尝试 ctype_xxx / filter_var / 内置正则。

规则参数形式

$v->rule('age', 'between:1,120');           // 规则串
$v->rule('age', ['between' => [1, 120]]);   // 数组
$v->rule('status', ['in' => [0, 1, 2]]);
$v->rule('role', [RoleEnum::class]);         // 枚举验证(enum 规则)

场景与分组

场景

同一验证器在不同接口验证不同字段:

class UserValidate extends Validate
{
    public function __construct()
    {
        $this->rule([
            'username' => 'require|alphaDash|length:4,20',
            'password' => 'require|length:6,32',
            'email'    => 'require|email',
        ]);
    }

    // scene: login
    protected function sceneLogin(): void
    {
        $this->only(['username', 'password']);
    }
}

$v = (new UserValidate())->scene('login');
$v->check($data);   // 只验证 username + password

scene() 也可直接传字段数组临时限定:$v->scene(['username', 'password'])。

白名单支持两种形态:字段名列表只限定验证范围;字段 => 规则映射在限定范围的同时覆盖该字段的规则(如 only(['password' => 'min:8']) 使编辑场景下密码非必填、仅在填写时校验长度)。

场景内增删改

$v->scene('login')
  ->remove('password', 'length')        // 移除 password 的 length 规则
  ->append('username', 'email')          // 追加规则
  ->replace('password', 'require');      // 覆盖规则

规则分组

独立校验组(闭包隔离作用域):

$v->group('strict', function (Validate $v) {
    $v->rule('username', 'require|alphaDash|length:6,20');
});

$v->check($data, 'strict');   // 按 strict 组验证

批量与异常

$v->batch(true)->check($data);           // 收集所有字段错误(不遇错即停)
$v->failException(true)->check($data);   // 失败抛 ValidateException
$v->getError(true);                       // [field => msg] 全量
$v->getErrors();                          // 始终返回数组

batch(true) 与 failException(true) 可组合:先收集所有字段错误,再一次性抛出携带完整错误列表的 ValidateException;不开启批量时遇第一个错误即抛。

捕获异常后业务可自行处理:

try {
    $v->failException(true)->check($data);
} catch (ValidateException $e) {
    $errors = $e->getError();   // array|string,原始形态
    $field  = $e->getKey();     // 失败字段名
}

约定式自动验证

在 FiberPHP 应用中,验证通过全局中间件自动触发,控制器无需手动调用 check()。

命名约定

App\Controller\Goods → App\Validate\Goods

将命名空间中的 \Controller\ 替换为 \Validate\,验证器与控制器同名(无后缀)。

触发条件

验证器类存在 且 定义了与控制器方法同名的 scene 时自动验证;否则静默放行(不强制全量验证)。

namespace App\Validate;

use FiberPHP\Validate\Validate;

class Goods extends Validate
{
    public function __construct()
    {
        $this->rule([
            'title' => 'require|length:2,100',
            'price' => 'require|float|gt:0',
        ]);
    }

    // 控制器 Goods::store() 触发本场景
    protected function sceneStore(): void
    {
        $this->only(['title', 'price']);
    }
}

验证失败抛 ValidateException(由框架异常处理器渲染为错误响应)。

中间件注册

骨架包自带 App\Middleware\ValidateMiddleware,在 config/http.php 中注册为全局中间件:

return [
    'middleware' => [
        'global' => [
            \App\Middleware\ValidateMiddleware::class,
        ],
    ],
];

多维数据

支持点号与 * 通配符取值:

$v->rule('user.name', 'require');
$v->rule('items.*.sku', 'require|alphaDash');

$v->check([
    'user'  => ['name' => 'tom'],
    'items' => [['sku' => 'A1'], ['sku' => '']],
]);
// → items.*.sku 验证失败

批量模式下同一通配字段有多个元素失败时,错误消息收集为该字段名下的列表(如 items.*.sku => ['错误1', '错误2']),不会互相覆盖。

错误消息

三级优先级:字段.规则 > 字段级 > typeMsg 默认。模板占位符::attribute(字段描述)、:rule(规则值)、:1 / :2 / :3 (逗号分隔的规则参数)。

$v->setTypeMsg(['email' => ':attribute 必须是合法邮箱']);
$v->message(['email.require' => '邮箱必填', 'email.email' => '邮箱格式不对']);
$v->field('email', '邮箱');

License

MIT License (c) 2026 庞斌,详见 LICENSE。