fiberphp/validate

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

Maintainers

Package info

gitee.com/FiberPHP/validate

Issues

pkg:composer/fiberphp/validate

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

dev-master 2026-08-30 15:49 UTC

This package is auto-updated.

Last update: 2026-08-30 15:50:02 UTC


README

FiberPHP 数据验证库。纯库实现(ValidateException 继承 \RuntimeException,不依赖框架),支持多规则链式验证、场景/分组、批量错误收集、点号与通配符多维数据访问,内置 40+ 验证规则与自定义扩展。

环境要求

  • PHP >= 8.3
  • ext-json
  • ext-mbstring
  • fiberphp/support dev-master(Arr / Str

安装

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 \FiberPHP\Validate\Exception\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= / sameeq<>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'])

场景内增删改

$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();                          // 始终返回数组

捕获异常后业务自行构造响应(纯库,不耦合 HTTP 层):

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

多维数据

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

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

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

错误消息

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

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

目录结构

src/
├── Validate.php                       # 核心:规则编排 + 验证执行 + 错误组装
├── Exception/
│   └── ValidateException.php          # 继承 \RuntimeException(纯库化)
└── Rules/
    ├── ComparisonRulesTrait.php        # confirm/different/egt/gt/elt/lt/eq/neq
    ├── ConditionalRulesTrait.php       # requireIf/requireWith/requireWithout/acceptedIf/...
    ├── DateRulesTrait.php              # after/before/dateFormat/expire
    ├── FileRulesTrait.php              # file/image/fileSize/fileExt/fileMime
    ├── NetworkRulesTrait.php          # activeUrl/ip/allowIp/denyIp
    ├── StringRulesTrait.php            # length/max/min/in/notIn/between/regex/...
    └── TypeRulesTrait.php             # require/accepted/boolean/number/integer/enum/array/is()

License

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