php-validate

by inhere

Lightweight and feature-rich PHP validation and filtering library. Support scene grouping, pre-filte...

215 Stars 25 Forks Last release: 6 months ago (v2.8.0) MIT License 214 Commits 58 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

PHP Validate

License Php Version Latest Stable Version Build Status Coverage Status Github Actions Status

一个简洁小巧且功能完善的php验证、过滤库。

  • 简单方便,支持添加自定义验证器
  • 支持前置验证检查, 自定义如何判断非空
  • 支持将规则按场景进行分组设置。或者部分验证
  • 支持在进行验证前对值使用过滤器进行净化过滤内置过滤器
  • 支持在进行验证前置处理和后置处理独立验证处理
  • 支持自定义每个验证的错误消息,字段翻译,消息翻译,支持默认值
  • 支持基本的数组检查,数组的子级(
    'goods.apple'
    )值检查, 通配符的子级检查 (
    'users.*.id' 'goods.*'
    )
  • 方便的获取错误信息,验证后的安全数据获取(只会收集有规则检查过的数据)
  • 已经内置了60多个常用的验证器内置验证器
  • 规则设置参考
    yii
    ,
    laravel
    ,
    Respect/Validation
  • 独立的过滤器
    Inhere\Validate\Filter\Filtration
    ,可单独用于数据过滤

两种规则配置方式

validate 同时支持两种规则配置方式,对应了两种规则的收集解析策略。

多字段单规则

  • Validation|RuleValidation
    : 每条规则中,允许多个字段,但只能有一个验证器。 (规则配置类似于Yii)

配置示例: (本文档的示例都是这种)

[
    ['tagId,userId,name,email,freeTime', 'required', ...],
    // ... ...
];

单字段多规则

  • FieldValidation
    : 每条规则中,只能有一个字段,但允许多个验证器。 (规则配置类似于Laravel)

配置示例:

[
    ['field', 'required|string:5,10|...', ...],
    // ... ...
]

更多配置示例请参看 像Laravel一样配置

项目地址

  • github https://github.com/inhere/php-validate.git
  • gitee https://gitee.com/inhere/php-validate.git

注意: master 分支是要求

php7.1+
的(推荐使用)。
1.x
分支是支持php5的代码分支,但是基本上不再维护。

安装

composer require inhere/php-validate
// composer require inhere/php-validate ^2.2

立即使用

方式1: 直接使用类
Validation

需要快速简便的使用验证时,可直接使用

Inhere\Validate\Validation
use Inhere\Validate\Validation;

class SomeController { public function demoAction() { $v = Validation::check($_POST,[ // add rule ['title', 'min', 40], ['freeTime', 'number'], ]);

    if ($v->isFail()) {
        var_dump($v->getErrors());
        var_dump($v->firstError());
    }

    // $postData = $v->all(); // 原始数据
    $safeData = $v->getSafeData(); // 验证通过的安全数据

    $db->save($safeData);
}

}

方式1: 继承类
Validation

创建一个新的class,并继承

Inhere\Validate\Validation
。用于一个(或一系列相关)请求的验证, 相当于 laravel 的 表单请求验证

此方式是最为完整的使用方式,可以配置规则,设置字段翻译,设置自定义的错误消息等

use Inhere\Validate\Validation;

class PageRequest extends Validation { # 进行验证前处理,返回false则停止验证,但没有错误信息,可以在逻辑中调用 addError 增加错误信息 public function beforeValidate(): bool { return true; } # 进行验证后处理,该干啥干啥 public function afterValidate(): bool { return true; }

public function rules(): array
{
    return [
        // 字段必须存在且不能为空
        ['tagId,title,userId,freeTime', 'required'],

        // 4<= tagId <=567
        ['tagId', 'size', 'min'=>4, 'max'=>567, 'filter' => 'int'],

           // title length >= 40. 注意只需一个参数的验证,无需加 key, 如这里的 40            ['title', 'min', 40, 'filter' => 'trim'],

           // 大于 0            ['freeTime', 'number'],

        // 含有前置条件
        ['tagId', 'number', 'when' => function($data) {
            return isset($data['status']) && $data['status'] > 2;
        }],

        // 在验证前会先过滤转换为 int。并且仅会在指明场景名为 'scene1' 时规则有效

           ['userId', 'number', 'on' => 'scene1', 'filter' => 'int'], ['username', 'string', 'on' => 'scene2', 'filter' => 'trim'],

        // 使用自定义正则表达式
        ['username', 'regexp' ,'/^[a-z]\w{2,12}$/'],

        // 自定义验证器,并指定当前规则的消息
        ['title', 'custom', 'msg' => '{attr} error msg!' ],

        // 直接使用闭包验证
        ['status', function($status) {
            if (is_int($status) && $status > 3) {
                return true;
            }
            return false;
        }],

           // 标记字段是安全可靠的 无需验证            ['createdAt, updatedAt', 'safe'], ]; }

// 定义不同场景需要验证的字段。
// 功能跟规则里的 'on' 类似,两者尽量不要同时使用,以免混淆。
public function scenarios(): array
{
    return [
        'create' => ['user', 'pwd', 'code'],
        'update' => ['user', 'pwd'],
    ];
}

// 定义字段翻译
public function translates(): array
{
    return [
      'userId' => '用户Id',
    ];
}

// 自定义验证器的提示消息, 默认消息请看 {@see ErrorMessageTrait::$messages}
public function messages(): array
{
    return [
      'required' => '{attr} 是必填项。',
      // 可以直接针对字段的某个规则进行消息定义
      'title.required' => 'O, 标题是必填项。are you known?',
    ];
}

// 添加一个验证器。必须返回一个布尔值标明验证失败或成功
protected function customValidator($title): bool
{
    // some logic ...
    // $this->getRaw('field'); 访问 data 数据

    return true; // Or false;
}

}

  • 使用
// 验证 POST 数据
$v = PageRequest::check($_POST);

// 验证失败 if ($v->isFail()) { var_dump($v->getErrors()); var_dump($v->firstError()); }

// 验证成功 ... $safeData = $v->getSafeData(); // 验证通过的安全数据 // $postData = $v->all(); // 原始数据

$db->save($safeData);

方式3: 使用trait
ValidationTrait

创建一个新的class,并使用 Trait

Inhere\Validate\ValidationTrait

此方式是高级自定义的使用方式, 可以方便的嵌入到其他类中。

如下,嵌入到一个数据模型类中, 实现一个简单的模型基类,添加数据库记录前自动进行验证

class DataModel
{
    use \Inhere\Validate\ValidationTrait;

protected $data = [];

protected $db;

/**
 * @param array $data
 * @return $this
 */
public function load(array $data)
{
    $this->data = $data;

    return $this;
}

public function create()
{
    if ($this->validate()->isFail()) {
        return false;
    }

    return $this->db->insert($this->getSafeData());
}

}

使用:

// on model class
class UserModel extends DataModel
{
    public function rules(): array
    {
        return [
            ['username, passwd', 'required'],
            ['passwd', 'compare', 'repasswd', 'on' => 'create']
            ['username', 'string', 'min' => 2, 'max' => 20, 'on' => 'create' ],
            ['id', 'number', 'on' => 'update' ], // 仅作用于场景 update
            ['createdAt, updatedAt', 'safe'],
        ];
    }
}

// on controller action ... class UserController { // in action // @api /user/add public function addAction() { $model = new UserModel; // 载入提交数据并设定场景为: create $model->load($_POST)->atScene('create');

    if (!$ret = $model->create()) {
        exit($model->firstError());
    }

    echo "add success: userId = $ret";
}

}

添加自定义验证器

  • 方式1在继承了
    Inhere\Validate\Validation
    的子类添加验证方法. 请看上面的 使用方式1

注意: 写在当前类里的验证器方法必须带有后缀

Validator
, 以防止对内部的其他的方法造成干扰
  • 方式2通过
    Validation::addValidator()
    添加自定义验证器. e.g:
$v = Validation::make($_POST,[
        // add rule
        ['title', 'min', 40],
        ['freeTime', 'number'],
        ['title', 'checkTitle'],
    ])
    ->addValidator('checkTitle',function($title) { // 第一个参数是字段值。最后一个参数总是 $data
        // some logic ...

    return true; // 成功返回 True。验证失败,返回 False.
}, '{attr} default message!')
->validate();

  • 方式3直接写闭包进行验证 e.g:
    ['status', function($status) { // 第一个参数是字段值。最后一个参数总是 $data
        if ($status > 3) {
            return true;
        }

    return false;
}]

  • 方式4定义一个闭包验证类进行验证,这种方法能提高验证方法的复用性

别忘了继承

\Inhere\Validate\Validator\AbstractValidator
,和实现必须方法
validate
class AdemoValidator extends \Inhere\Validate\Validator\AbstractValidator
{


public function validate($value, $data): bool 
{
    if ($value == 1) {
        return true;
    }
    return false;
}

}

['status', new AdemoValidator()]

验证前置/后置处理

  • 方式1: 在
    Validation

该方法与

onBeforeValidate
&
onAfterValidate
有冲突
use Inhere\Validate\Validation;

class PageValidation extends Validation { # 进行验证前处理,返回false则停止验证,但没有错误信息,可以在逻辑中调用 addError 增加错误信息 public function beforeValidate(): bool { return true; } # 进行验证后处理,该干啥干啥 public function afterValidate(): bool { return true; } }

  • 方式2:
    onBeforeValidate
    &
    onAfterValidate
    ```php use Inhere\Validate\Validation;

$v = Validation::make(['name' => 'inhere'], [ ['name', 'string', 'min' => 3, 'filter' => 'trim|upper'] ]);

$v->onBeforeValidate(function (Validation $v) { return true; });

$v->onAfterValidate(function (Validation $v) {

});

$v->validate(); ```

一个完整的规则示例

一个完整的规则示例, 包含了所有可添加的项。

注意:

  • 每条规则的第一个元素必须要验证的字段(可以同时配置多个,可以是数组. type:
    string|array
    )
  • 第二个元素必须一个验证器(字符串,闭包,可回调的对象或数组. type:
    string|Closure|callable
    )
  • 后面紧跟着 是验证器可能需要的参数信息 (若验证器需要的参数只有一个,则参数无需带key)
  • 然后就是其他选项配置(
    msg
    ,
    on
    ,
    filter
    , ...)
// a full rule
[
 // basic validate setting
 'field0,field1,...', 'validator', 'arg0', 'arg1', ...,

// some extended option settings 'skipOnEmpty' => 'bool', 'msg' => 'string|array', 'default' => 'mixed', 'on' => 'string|array' 'isEmpty' => 'callback(string|closure)', 'when' => 'callback(string|closure)', 'filter' => 'callback(string|array|closure)' ]

字段验证器

FieldValidation
的配置类似,只是 只有一个字段,而验证器允许有多个

规则选项设置

除了可以添加字段的验证之外,还有一些特殊关键词可以设置使用,以适应各种需求。

default
-- 设置字段的默认值

给一个或多个字段设置一个默认值。

['page', 'number', 'default' => 1],
['pageSize', 'number', 'default' => 15],

NOTICE: 默认值也会被验证器验证

msg
-- 设置错误提示消息

设置当前规则的错误提示消息, 设置了后就不会在使用默认的提示消息。

['title', 'customValidator', 'msg' => '{attr} error msg!' ], // 指定当前规则的消息
// o, 可以是数组哦 :)
['tagId,title,userId,freeTime', 'required', 'msg' => [
  'tagId' => 'message ...',
  'userId' => 'message 1 ...',
]],

on
-- 设置规则使用场景

如果需要让定义的规则在多个类似情形下重复使用,可以设置规则的使用场景。在验证时也表明要验证的场景

    // 在继承了 Validation 的子类 ValidationClass 中 ...
    public function rules(): array
    {
         return [
            ['title', 'required' ],
            ['userId', 'number', 'on' => 'create' ],
            ['userId', 'int', 'on' => 'update' ],
            ['name', 'string', 'on' => 'create,update' ],
        ];
    }

使用:

如,在下面指定了验证场景时,将会使用上面的第 1,3,4 条规则. (第 1 条没有限制规则使用场景的,在所有场景都可用)

    // ...
    $valid = ValidationClass::make($_POST)->atScene('update')->validate();
    // ...

when
-- 规则的前置条件

只有在先满足了(

when
)前置条件时才会验证这条规则

如在下面的例子中,检查到第二条规则时,会先执行闭包(

when
), 当其返回
true
验证此条规则,否则不会验证此条规则
    // 在继承了 Validation 的子类中 ...
    public function rules(): array
    {
         return [
            ['title', 'required' ],
            ['tagId', 'number', 'when' => function($data) {
               return isset($data['status']) && $data['status'] > 2;
            }],
        ];
    }

skipOnEmpty
-- 为空是否跳过验证

当字段值为空时是否跳过验证,默认值是

true
. (参考自 yii2)

'required*' 规则不在此限制内.

如,有一条规则:

['name', 'string']

提交的数据中 没有

name
字段或者
$data['name']
等于空都不会进行
string
验证; 只有当
$data['name']
有值且不为空 时才会验证是否是
string

如果要想为空时也检查, 请将此字段同时加入

required
规则中.
['name', 'required' ]
['name', 'string' ]

或者也可以设置

'skipOnEmpty' => false
:
['name', 'string', 'skipOnEmpty' => false ]

如何确定值为空 关于为空

isEmpty
-- 是否为空判断

是否为空判断, 这个判断作为

skipOnEmpty
的依据. 默认使用
Validators::isEmpty
来判断.

你也可以自定义判断规则:

['name', 'string', 'isEmpty' => function($value) {
    return true or false;
 }]

自定义 isEmpty 验证时,应留意 $value 是否为 ArrayValueNotExists 实例

['users.*.id', 'each', 'required', 'isEmpty' => function($value) {
    if ($value instanceof \Inhere\Validate\ArrayValueNotExists) {
        return true;
    }
    // your code here ...
}]

filter
-- 使用过滤器

支持在进行验证前对值使用过滤器进行净化过滤内置过滤器

['tagId,userId,freeTime', 'number', 'filter' => 'int'],
['field', 'validator', 'filter' => 'filter0|filter1...'],

// 需要自定义性更高时,可以使用数组。 ['field1', 'validator', 'filter' => [ 'string', 'trim', ['Class', 'method'], ['Object', 'method'], // 追加额外参数。 传入时,第一个参数总是要过滤的字段值,其余的依次追加 'myFilter' => ['arg1', 'arg2'], // 直接使用闭包 function($val) { return str_replace(' ', '', $val); }, ]],

提示:

  • 允许同时使用多个过滤器。字符串使用
    |
    分隔,或者配置为数组。
  • 注意: 写在当前类里的过滤器方法必须带有后缀
    Filter
    , 以防止对内部的其他的方法造成干扰
  • 通过类
    Filtration
    ,可以独立使用过滤器功能
  • php内置过滤器请参看 http://php.net/manual/zh/filter.filters.sanitize.php

场景验证

如果需要让定义的规则在多个类似情形下重复使用,可以设置规则的使用场景。 在验证时也表明要验证的场景

方式1

在继承类中使用

scenarios()
方法:
    // 在继承了 Validation 的子类 ValidationClass 中 ...

// 定义不同场景需要验证的字段。
// 功能跟规则里的 'on' 类似,两者尽量不要同时使用,以免混淆。
public function scenarios(): array
{
    return [
        'create' => ['user', 'pwd', 'code'],
        'update' => ['user', 'pwd'],
    ];
}

方式2

添加规则时配置

on
选项:
    // 在继承了 Validation 的子类 ValidationClass 中 ...
    public function rules(): array
    {
         return [
            ['title', 'required' ],
            ['userId', 'number', 'on' => 'create' ],
            ['userId', 'int', 'on' => 'update' ],
            ['name', 'string', 'on' => 'create,update' ],
        ];
    }

验证使用

$v->setSecne('update')->validate();

内置的过滤器

一些 php 内置的函数可直接使用。 e.g

trim|ucfirst
json_decode
md5

过滤器

说明 示例

abs
| 返回绝对值 |
['field', 'int', 'filter' => 'abs'],
int/integer
| 过滤非法字符并转换为
int
类型 支持数组 |
['userId', 'number', 'filter' => 'int'],
bool/boolean
| 转换为
bool
关于bool值 |
['argee', 'bool']
float
| 过滤非法字符,保留
float
格式的数据 |
['price', 'float', 'filter' => 'float'],
string
| 过滤非法字符并转换为
string
类型 |
['userId', 'number', 'filter' => 'string'],
trim
| 去除首尾空白字符,支持数组。 |
['username', 'min', 4, 'filter' => 'trim'],
nl2br
| 转换
\n
\r\n
\r

|
['content', 'string', 'filter' => 'nl2br'],
lower/lowercase
| 字符串转换为小写 |
['description', 'string', 'filter' => 'lowercase'],
upper/uppercase
| 字符串转换为大写 |
['title', 'string', 'filter' => 'uppercase'],
snake/snakeCase
| 字符串转换为蛇形风格 |
['title', 'string', 'filter' => 'snakeCase'],
camel/camelCase
| 字符串转换为驼峰风格 |
['title', 'string', 'filter' => 'camelCase'],
timestamp/strToTime
| 字符串日期转换时间戳 |
['pulishedAt', 'number', 'filter' => 'strToTime'],
url
| URL 过滤,移除所有不符合 URL 的字符 |
['field', 'url', 'filter' => 'url'],
str2list/str2array
| 字符串转数组
'tag0,tag1' -> ['tag0', 'tag1']
|
['tags', 'strList', 'filter' => 'str2array'],
unique
| 去除数组中的重复值(by
array_unique()
) |
['tagIds', 'intList', 'filter' => 'unique'],
email
| email 过滤,移除所有不符合 email 的字符 |
['field', 'email', 'filter' => 'email'],
encoded
| 去除 URL 编码不需要的字符,与
urlencode()
函数很类似 |
['imgUrl', 'url', 'filter' => 'encoded'],
clearSpace
| 清理空格 |
['title', 'string', 'filter' => 'clearSpace'],
clearNewline
| 清理换行符 |
['title', 'string', 'filter' => 'clearNewline'],
clearTags/stripTags
| 相当于使用
strip_tags()
|
['content', 'string', 'filter' => 'clearTags'],
escape/specialChars
| 相当于使用
htmlspecialchars()
转义数据 |
['content', 'string', 'filter' => 'specialChars'],
quotes
| 应用
addslashes()
转义数据 |
['content', 'string', 'filter' => 'quotes'],

内置的验证器

/
分隔的验证器,表明功能是一样的,只是有不同的别名

验证器

说明 规则示例

required
| 要求此字段/属性是必须的(不为空的)。关于为空 |
['tagId, userId', 'required' ]
int/integer
| 验证是否是 int 支持范围检查 |
['userId', 'int']
['userId', 'int', 'min'=>4, 'max'=>16]
num/number
| 验证是否是 number(大于0的整数) 支持范围检查 |
['userId', 'number']
['userId', 'number', 'min'=>4, 'max'=>16]
bool/boolean
| 验证是否是 bool. 关于bool值 |
['open', 'bool']
float
| 验证是否是 float |
['price', 'float']
string
| 验证是否是 string. 支持长度检查 |
['name', 'string']
,
['name', 'string', 'min'=>4, 'max'=>16]
accepted
| 验证的字段必须为
yes/on/1/true
这在确认「服务条款」是否同意时有用(ref laravel) |
['agree', 'accepted']
url
| 验证是否是 url |
['myUrl', 'url']
email
| 验证是否是 email |
['userEmail', 'email']
alpha
| 验证值是否仅包含字母字符 |
['name', 'alpha']
alphaNum
| 验证是否仅包含字母、数字 |
['field', 'alphaNum']
alphaDash
| 验证是否仅包含字母、数字、破折号( - )以及下划线( _ ) |
['field', 'alphaDash']
map/isMap
| 验证值是否是一个非自然数组 map (key - value 形式的) |
['goods', 'isMap']
list/isList
| 验证值是否是一个自然数组 list (key是从0自然增长的) |
['tags', 'isList']
array/isArray
| 验证是否是数组 |
['goods', 'isArray']
each
| 对数组中的每个值都应用给定的验证器(这里的绝大多数验证器都可以使用),并且要全部通过 |
['goods.*','each','string']
,
['goods.*','each','string','min'=>3]
hasKey
| 验证数组存在给定的key(s) |
['goods', 'hasKey', 'pear']
['goods', 'hasKey', ['pear', 'banana']]
distinct
| 数组中的值必须是唯一的 |
['goods', 'distinct']
,
['users.*.id', 'distinct']
ints/intList
| 验证字段值是否是一个 int list |
['tagIds', 'intList']
numList
| 验证字段值是否是一个 number list |
['tagIds', 'numList']
strings/strList
| 验证字段值是否是一个 string list |
['tags', 'strList']
arrList
| 验证字段值是否是一个 array list(多维数组) |
['tags', 'arrList']
min
| 最小边界值验证 |
['title', 'min', 40]
max
| 最大边界值验证 |
['title', 'max', 40]
size/range/between
| 验证大小范围, 可以支持验证
int
,
string
,
array
数据类型 |
['tagId', 'size', 'min'=>4, 'max'=>567]
length
| 长度验证( 跟
size
差不多, 但只能验证
string
,
array
的长度 |
['username', 'length', 'min' => 5, 'max' => 20]
fixedSize/sizeEq/lengthEq
| 固定的长度/大小(验证
string
,
array
长度,
int
大小) |
['field', 'fixedSize', 12]
startWith
| 值(
string/array
)是以给定的字符串开始 |
['field', 'startWith', 'hell']
endWith
| 值(
string/array
)是以给定的字符串结尾 |
['field', 'endWith', 'world']
in/enum
| 枚举验证: 包含 |
['status', 'in', [1,2,3]]
notIn
| 枚举验证: 不包含 |
['status', 'notIn', [4,5,6]]
inField
| 枚举验证: 字段值 存在于 另一个字段(anotherField)的值中 |
['field', 'inField', 'anotherField']
eq/mustBe
| 必须是等于给定值 |
['status', 'mustBe', 1]
ne/neq/notBe
| 不能等于给定值 |
['status', 'notBe', 0]
eqField
| 字段值比较: 相同 |
['passwd', 'eqField', 'repasswd']
neqField
| 字段值比较: 不能相同 |
['userId', 'neqField', 'targetId']
ltField
| 字段值比较: 小于 |
['field1', 'ltField', 'field2']
lteField
| 字段值比较: 小于等于 |
['field1', 'lteField', 'field2']
gtField
| 字段值比较: 大于 |
['field1', 'gtField', 'field2']
gteField
| 字段值比较: 大于等于 |
['field1', 'gteField', 'field2']
requiredIf
| 指定的其它字段( anotherField )值等于任何一个
value
时,此字段为 必填(ref laravel) |
['city', 'requiredIf', 'myCity', ['chengdu'] ]
requiredUnless
| 指定的其它字段( anotherField )值等于任何一个
value
时,此字段为 不必填(ref laravel) |
['city', 'requiredUnless', 'myCity', ['chengdu'] ]
requiredWith
| 指定的字段中的 任意一个 有值且不为空,则此字段为 必填(ref laravel) |
['city', 'requiredWith', ['myCity'] ]
requiredWithAll
| 如果指定的 所有字段 都有值,则此字段为 必填(ref laravel) |
['city', 'requiredWithAll', ['myCity', 'myCity1'] ]
requiredWithout
| 如果缺少 任意一个 指定的字段值,则此字段为 必填(ref laravel) |
['city', 'requiredWithout', ['myCity', 'myCity1'] ]
requiredWithoutAll
| 如果所有指定的字段 都没有值,则此字段为 必填(ref laravel) |
['city', 'requiredWithoutAll', ['myCity', 'myCity1'] ]
date
| 验证是否是 date |
['publishedAt', 'date']
dateFormat
| 验证是否是 date, 并且是指定的格式 |
['publishedAt', 'dateFormat', 'Y-m-d']
dateEquals
| 验证是否是 date, 并且是否是等于给定日期 |
['publishedAt', 'dateEquals', '2017-05-12']
beforeDate
| 验证字段值必须是给定日期之前的值(ref laravel) |
['publishedAt', 'beforeDate', '2017-05-12']
beforeOrEqualDate
| 字段值必须是小于或等于给定日期的值(ref laravel) |
['publishedAt', 'beforeOrEqualDate', '2017-05-12']
afterOrEqualDate
| 字段值必须是大于或等于给定日期的值(ref laravel) |
['publishedAt', 'afterOrEqualDate', '2017-05-12']
afterDate
| 验证字段值必须是给定日期之前的值 |
['publishedAt', 'afterDate', '2017-05-12']
json
| 验证是否是json字符串(默认严格验证,必须以
{
[
开始) |
['goods', 'json']
['somedata', 'json', false]
- 非严格,普通字符串
eg 'test'
也会通过
file
| 验证是否是上传的文件 |
['upFile', 'file']
image
| 验证是否是上传的图片文件 |
['avatar', 'image']
, 限定后缀名
['avatar', 'image', 'jpg,png']
ip
| 验证是否是 IP |
['ipAddr', 'ip']
ipv4
| 验证是否是 IPv4 |
['ipAddr', 'ipv4']
ipv6
| 验证是否是 IPv6 |
['ipAddr', 'ipv6']
macAddress
| 验证是否是 mac Address |
['field', 'macAddress']
md5
| 验证是否是 md5 格式的字符串 |
['passwd', 'md5']
sha1
| 验证是否是 sha1 格式的字符串 |
['passwd', 'sha1']
color
| 验证是否是html color |
['backgroundColor', 'color']
regex/regexp
| 使用正则进行验证 |
['name', 'regexp', '/^\w+$/']
safe
| 用于标记字段是安全的,无需验证 |
['createdAt, updatedAt', 'safe']

safe
验证器,标记属性/字段是安全的

特殊验证器 用于标记字段是安全的,无需验证,直接加入到安全数据中。

比如我们在写入数据库之前手动追加的字段: 创建时间,更新时间。

['createdAt, updatedAt', 'safe']

一些补充说明

关于为空判断

字段符合下方任一条件时即为「空」

  • 该值为
    null
    .
  • 该值为空字符串
    ''
  • 该值为空数组
    []
  • 该值为空对象 -- 空的
    可数
    对象
  • 该值为没有路径的上传文件

关于布尔值

值符合下列的任意一项即认为是为bool值(不区分大小写)

  • 是 "1"、"true"、"on" 和 "yes" (
    TRUE
    )
  • 是 "0"、"false"、"off"、"no" 和 "" (
    FALSE
    )

关于文件验证

文件验证时注意要设置文件信息源数据

$v = Validation::make($_POST, [
    // [...],
    // some rules ...
])
->setUploadedFiles($_FILES)
->validate();
// ...

提示和注意

  • 请将
    required*
    系列规则写在规则列表的最前面
  • 规则上都支持添加过滤器
  • 验证大小范围
    int
    是比较大小。
    string
    array
    是检查长度。大小范围 是包含边界值的
  • size/range
    length
    可以只定义
    min
    或者
    max
  • 支持对数组的子级值验证
[
    'goods' => [
        'apple' => 34,
        'pear' => 50,
    ],
]

规则:

    ['goods.pear', 'max', 30], //goods 下的 pear 值最大不能超过 30
  • 支持对数组的子级值进行遍历验证
[
  'goods' => [
       'apple' => 34,
       'pear' => 50,
   ],
  'users' => [
       ['id' => 34, 'name' => 'tom'],
       ['id' => 89, 'name' => 'john'],
   ]
]
    ['goods.*', 'each', 'number'], //goods 下的 每个值 都必须为大于0 的整数
    // 写法是等效的
    // ['goods', 'each', 'number'], //goods 下的 每个值 都必须为大于0 的整数

// 多维数组
['users.*.id', 'each', 'required'],
['users.*.id', 'each', 'number', 'min' => 34],
['users.*.name', 'each', 'string', 'min' => 5],

  • 对于带有通配符
    *
    的字段, 添加过滤器是无效的

一些关键方法API

设置验证场景

public function setScene(string $scene)
public function atScene(string $scene) // setScene 的别名方法

设置当前验证的场景名称。将只会使用符合当前场景的规则对数据进行验证

进行数据验证

public function validate(array $onlyChecked = [], $stopOnError = null)

进行数据验证。 返回验证器对象,然后就可以获取验证结果等信息。

  • $onlyChecked
    可以设置此次需要验证的字段
  • $stopOnError
    是否当出现一个验证失败就立即停止。 默认是
    true

添加自定义的验证器

public function addValidator(string $name, \Closure $callback, string $msg = '')

添加自定义的验证器。 返回验证器对象以支持链式调用

  • $name
    自定义验证器名称
  • $callback
    自定义验证器。处理验证,为了简洁只允许闭包。
  • $msg
    可选的。 当前验证器的错误消息

判断验证是否通过

// 验证失败
public function isFail()
public function hasError() // isFail() 的别名方法

// 成功通过验证 public function isOk() public function isPassed()

获取验证是否通过(是否有验证失败)。

获取所有错误信息

public function getErrors(): array

获取所有的错误信息, 包含所有错误的字段和错误信息的多维数组。 eg:

[
    ['name' => 'field1', 'msg' => 'error Message1' ],
    ['name' => 'field2', 'msg' => 'error Message2' ],
    ...
]

同一个属性/字段也可能有多个错误消息,当为它添加了多个验证规则时。

得到第一个错误信息

public function firstError($onlyMsg = true)
  • $onlyMsg
    是否只返回消息字符串。当为 false,返回的则是数组 eg:
    ['name' => 'field', 'msg' => 'error message']

得到最后一个错误信息

public function lastError($onlyMsg = true)
  • $onlyMsg
    是否只返回消息字符串。当为 false,返回的则是数组 eg:
    ['name' => 'field', 'msg' => 'error message']

获取所有验证通过的数据

public function getSafeData(): array|\stdClass

获取所有 验证通过 的安全数据.

  • 此数据数组只包含加入了规则验证的字段数据,不会含有额外的字段。(可直接省去后续的字段收集)
  • 推荐使用此数据进行后续操作,比如存入数据库等。

注意: 当有验证失败出现时,安全数据

safeData
将会被重置为空。 即只有全部通过验证,才能获取到
safeData

根据字段名获取安全值

public function val(string $key, $default = null) // getSafe() 的别名方法
public function getValid(string $key, $default = null) // getSafe() 的别名方法
public function getSafe(string $key, $default = null)

验证通过 的数据中取出对应 key 的值

获取所有原始数据

public function all(): array

获取验证时传入的所有数据

根据字段名获取原始数据的值

public function getRaw(string $key, $default = null)

从验证时传入的数据中取出对应 key 的值

代码示例

可运行示例请看

example

单元测试

phpunit

License

MIT

我的其他项目

  • inhere/console 轻量且功能丰富的命令行应用, 控制台交互,工具库
  • inhere/sroute 轻量且快速的HTTP请求路由库

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.