WebGeeker-Validation: 一个强大的 PHP 参数验证器

WebGeeker-Validation: 一个强大的 PHP 参数验证器

项目地址: github 码云

用于对API接口的请求参数进行合法性检查。

在实现服务端的API接口时,对于每一个接口的每一个参数,都应该检测其取值是否合法,以免错误的数据输入到系统中。这个工作可以说是费时费力,但又不得不做。而且PHP本身是弱类型语言,不但要验证取值,还要验证数据的类型是否符合,这就更复杂了。

本工具就是针对这个工作而设计的,能够有效地减少编码量,代码可读性好。

看看下面这段代码,可以对用法有个大概印象,应该不难看懂:

$params = $request->query(); // 获取GET参数

// 验证(如果验证不通过,会抛出异常)
Validation::validate($params, [
    "offset" => "IntGe:0",
    "count" => "Required|IntGeLe:1,200",
]);

支持多种数据类型的校验:整型、浮点型、bool型、字符串、数组、对象、文件、日期时间,能够验证嵌套的数据结构中的参数,还支持带条件判断的验证。

1 简介

1.1 为什么要写这样一个工具?

我在使用Laravel框架的时候,Laravel提供了一个参数验证工具,不过用起来不怎么顺畅:

  • 每一个验证都写一个验证类(继承XXX),这样太麻烦,而且系统中会多出许多许多的类;如果这些类在多处被复用,或者为了“更加”复用(减少重复代码),再在这些类之间搞出很多的继承关系,那么这些类的维护本身就是一个大问题;
  • 验证器有“一词多义”的问题。比如它有一个size验证器,它同时支持验证字符串、整型、文件等多种类型的参数,针对不同数据类型size的含义不一样。这就好比你去背英语单词,有那么一些英语单词,它有很多很多意思,不同的语境下有不同的含义。比如"present"这个单词,它既有“呈现”、“出席”的意思,也有“礼物”的意思。这种一词多义的单词最让人头疼了,搞不清它到底什么意思,而且记不住啊。

为了解决这些问题,所以才写了这么一个工具。

1.2 特点

  1. 简洁,验证逻辑一目了然(参考后面的例子)
  2. 轻量,不需要定义和维护各种验证classes
  3. 验证器语义明确,没有“一词多义”的问题
  4. 支持正则表达式验证
  5. 支持条件验证
  6. 理论上能够支持验证无限嵌套的参数
  7. 易学易记。比如整型验证器都是以"Int"开头,浮点型验证器都是以"Float"开头,等等。唯一不符合这一规则的是字符串型验证器,它们一部分以"Str"开头的,但也有一部分不以"Str"开头,比如Regexp, Ip, Email, Url等。
  8. 不绑定任何一个框架,无任何依赖。你可以在任何一个框架中使用这个工具,就算你不使用框架,也可以使用本工具。
  9. 每个功能特性都有单元测试(共有 41 tests, 369 assertions)

1.3 一个简单示例

下面这个示例展示了一个查询获取用户投诉列表的Request参数的验证(用到了条件验证和针对嵌套数据结构的验证):

//验证规则
$validations = [
    "offset" => "IntGe:0", // 参数offset应该大于等于0
    "count" => "Required|IntGeLe:1,200", // 参数count是必需的且大于等于1小于等于200
    "type" => "IntIn:1,2", // 参数type可取值为: 1, 2
    "state" => [
        'IfIntEq:type,1|IntEq:0', // 如果type==1(批评建议),那么参数state只能是0
        'IfIntEq:type,2|IntIn:0,1,2', // 如果type==2(用户投诉),那么参数state可取值为: 1, 2, 3
    ],
    "search.keyword" => "StrLenGeLe:1,100", // search.keyword 应该是一个长度在[1, 100]之间的字符串
    "search.start_time" => "Date", // search.start_time 应该是一个包含合法日期的字符串
    "search.end_time" => "BoolSmart", // search.end_time 应该是一个包含合法日期的字符串
];

// 待验证参数
$params = [
    "offset" => 0, // 从第0条记录开始
    "count" => 10, // 最多返回10条记录
    "type" => 2, // 1-批评建议, 2-用户投诉
    "state" => 0, // 0-待处理, 1-处理中, 2-已处理
    "search" => [ // 搜索条件
        "keyword" => '硬件故障', // 关键字
        "start_time" => "2018-01-01", // 起始日期
        "end_time" => "2018-01-31", // 结束日期
    ],
];

// 验证(如果验证不通过,会抛出异常)
Validation::validate($params, $validations);

2 安装

通过Composer安装

composer require webgeeker/validation:^0.4

3 快速上手

3.1 一个完整的示例(不使用任何框架)

这个例子直接验证$_POST(POST表单)中的参数,展示了最基本的用法

<?php
include "vendor/autoload.php";

use WebGeeker\Validation\Validation;

try {
    Validation::validate($_POST, [
        "offset" => "IntGe:0", // 参数offset应该大于等于0
        "count" => "Required|IntGeLe:1,200", // 参数count是必需的且大于等于1小于等于200
    ]);
} catch (\Exception $e) {
    echo $e->getMessage();
}

注意:验证不通过会抛出异常,该异常中包含有错误描述信息

3.2 验证不通过的错误处理

如果验证不通过,Validation::validate(...)方法会抛出异常,建议在框架层面统一捕获这些异常,提取错误描述信息并返回给客户端。

3.3 在第三方框架中的用法

第三方框架一般会提供Request对象,可以取到GET, POST参数(以Laravel为例)

//$params = $request->query(); // 获取GET参数
$params = $request->request->all(); // 获取POST参数

// 验证(如果验证不通过,会抛出异常)
Validation::validate($params, [
    // 此处省略验证规则
]);

4 详细使用方法

4.1 验证整型参数

整型验证器全部以"Int"开头,用于验证整型数值(如123)或整型字符串(如"123")。其它数据类型均不匹配。

"size" => "IntGeLe:1,100"

这条验证要求参数"size"是整数,并且大于等于1,小于等于100。

完整的整型验证器的列表参考附录 A.1 。

4.2 验证浮点型参数

浮点型验证器全部以"Float"开头,用于验证浮点型数值(如1.0)、浮点型字符串(如"1.0")、整型数值(如123)或整型字符串(如"123")。其它数据类型均不匹配。

"height" => "FloatGeLe:0.0,100.0"

这条验证要求参数"height"是浮点数,并且大于等于0,小于等于100.0。

完整的浮点型验证器的列表参考附录 A.2 。

4.3 验证bool型参数

bool型验证器只有两个:

  • Bool: 合法的取值为: true, false, "true", "false"(字符串忽略大小写)。
  • BoolSmart: 合法的取值为: true, false, "true", "false", 1, 0, "1", "0", "yes", "no", "y", "n"(字符串忽略大小写)

"accept" => "BoolSmart"

完整的bool型验证器的列表参考附录 A.3 。

4.4 验证字符串型参数

字符串型验证器不全以"Str"开头。只接收字符串型数据,其它数据类型均不匹配。

例1:

"name" => "StrLenGeLe:2,20"

这条验证要求参数"name"是字符串,长度在2-20之间(字符串长度是用mb_strlen()来计算的)。

例2:

"comment" => "ByteLenLe:1048576"

这条验证要求参数"comment"是字符串,字节长度不超过1048576(字节长度是用strlen()来计算的)。

例3:

"email" => "Email"

这条验证要求参数"email"是必须是合法的电子邮件地址。

例4(正则表达式验证):

"phone" => "Regexp:/^1(3[0-9]|4[579]|5[0-35-9]|7[0135678]|8[0-9]|66|9[89])\d{8}$/"

这条验证要求参数"phone"是合法的手机号。

关于正则表达式中的哪些特殊字符需要转义的问题,只需要用 preg_match() 函数验证好,如:

preg_match('/^string$/', $string);

然后把两个'/'号及其中间的部分拷贝出来,放在Regexp:后面即可,不需要再做额外的转义,即使正则中有'|'这种特殊符号,也不需要再转义。

完整的字符串型验证器的列表参考附录 A.4 。

4.5 验证数组型、对象型、文件型、日期时间型参数

参考附录A.5-A.8

4.6 验证器串联(与)

一条规则中可以有多个验证器前后串联,它们之间是“AND”的关系,如:

"file" => "FileMaxSize:10m|FileImage"

这个验证要求参数"file"是一个图像文件,并且文件大小不超过10m

4.7 Required 验证器

  • Required验证器要求参数必须存在,且其值不能为null(这个是PHP的null值,而不是字符串"null")(参数值为null等价于参数不存在)。
  • 如果多个验证器串联,Required验证器必须在其它验证器前面。
  • 如果还有条件验证器,Required必须串联在条件验证器后面。
  • 如果验证规则中没有 Required,当参数存在时才进行验证,验证不通过会抛异常;如果参数不存在,那么就不验证(相当于验证通过)

例:

"size" => "Required|StrIn:small,middle,large"

该验证要求参数"size"必须是字符串的"small", "middle"或者"large"。

4.8 忽略所有 Required 验证器

比如当创建一个用户时,要求姓名、性别、年龄全部都要提供;但是当更新用户信息时,不需要提供全部信息,提供哪个信息就更新哪个信息。

$validations = [
    "name" => "Required|StrLenGeLe:2,20",
    "sex" => "Required|IntIn:0,1",
    "age" => "Required|IntGeLe:1,200",
];

$userInfo = [
    "name" => "tom",
    "sex" => "0",
    "age" => "10",
];
Validation::validate($userInfo, $validations); // 创建用户时的验证

unset($userInfo["age"]); // 删除age字段
Validation::validate($userInfo, $validations, true); // 更新用户信息时的验证

注意上面代码的最后一行:validate()函数的第三个参数为true表示忽略所有的 Required 验证器。

这样我们就只需要写一份验证规则,就可以同时用于创建用户和更新用户信息这两个接口。

4.9 嵌套参数的验证

下面这个例子展示了包含数组和对象的嵌套的参数的验证:

$params = [
    "comments" => [
        [
            "title" => "title 1",
            "content" => "content 1",
        ],
        [
            "title" => "title 1",
            "content" => "content 1",
        ],
        [
            "title" => "title 1",
            "content" => "content 1",
        ],
    ]
];

$validations = [
    "comments[*].title" => "Required|StrLenGeLe:2,50",
    "comments[*].content" => "Required|StrLenGeLe:2,500",
];

Validation::validate($params, $validations);

4.10 条件判断型验证器

条件判断型验证器都以"If"开头。

比如你想招聘一批模特,男的要求180以上,女的要求170以上,验证可以这样写:

$validations = [
    "sex" => "StrIn:male,female",
    "height" => [
        "IfStrEq:sex,male|IntGe:180",
        "IfStrEq:sex,female|IntGe:170",
    ],
];

参数"sex"的值不同,参数"height"的验证规则也不一样。

完整的条件判断型验证器的列表参考附录 A.9 。

4.11 验证规则并联(或)

多条验证规则可以并联,它们之间是“或”的关系,如

"type" => [
    "StrIn:small,middle,large",
    "IntIn:1,2,3",
]

上面这条验证要求参数"type"既可以是字符串"small", "middle"或"large",也可以整型的1, 2或3

验证规则并联不是简单的“或”的关系,具体验证流程如下:

  1. 按顺序验证这些规则,如果有一条验证规则通过, 则该参数验证通过。
  2. 如果全部验证规则都被忽略(If验证器条件不满足,或者没有Required验证器并且该参数不存在,或者有0条验证规则),也算参数验证通过。
  3. 上面两条都不满足, 则该参数验证失败。

这些规则如果要完全理清并不是一件容易的事,所以不建议使用验证规则并联,也尽量不要设计需要这种验证方式的参数。

4.12 关于特殊值null, ""0false的问题

这些特殊的值是不等价的,它们是不同的数据类型(需要用不同的验证器去验证):

  • ""是字符串。
  • 0是整型。
  • false是bool型。
  • null是PHP的空。在本工具中它有特殊的含义。

如果某个参数的值为null,则本工具会视为该参数不存在。

比如下面两个array对于本工具来说是等价的.

$params = [
    "name" => "hello",
];

$params = [
    "name" => "hello",
    "comment" => null,
];

是等价的。

4.13 关于基本数据类型与字符串的关系

对于以下url地址

http://abc.com/index.php?p1=&&p2=hello&&p3=123

我们将得到的参数数组:

$params = [
    "p1" => "",
    "p2" => "hello",
    "p3" => "123",
];

注意

  • 参数"p1"的值为空字符串"",而不是null
  • 参数"p3"的值为字符串"123",而不是整型123
  • GET方式的HTTP请求是传递不了null值的。

本工具的所有验证器都是强类型的,"Int"验证的是整型,"Float"验证的是浮点型,"Str*"验证的是字符串型,数据类型不匹配,验证是通不过的。但是字符串类型是个例外。

因为常规的HTTP请求,所有的基本数据类型最终都会转换成字符串,所以:

  • 整型123和字符串"123"均可以通过验证器"Int"的验证;
  • 浮点型123.0和字符串"123.0"均可以通过验证器"Float"的验证;
  • bool型true和字符串"true"均可以通过验证器"Bool"的验证;
  • 但是null值和字符串"null"永远不等价,字符串"null"就只是普通的字符串。

4.14 自定义错误信息输出文本

如果参数验证不通过,Validation::validate()方法会抛出异常,这个异常会包含验证不通过的错误信息描述的文本。

但是这个描述文本对用户来说可能不那么友好,我们可以通过两个伪验证器来自定义这些文本:

  • Alias 用于自定义参数名称(这个名称会与内部的错误信息模版相结合,生成最终的错误信息描述文本)
  • >>> 用于自定义错误描述文本(这个文本会完全取代模版生成的错误描述文本)。

看下面的例子:

$params = [
    "title" => "a",
];

Validation::validate($params, [
    "title" => "Required|StrLenGeLe:2,50",
]); // 抛出异常的错误描述为:“title”长度必须在 2 - 50 之间

Validation::validate($params, [
    "title" => "Required|StrLenGeLe:2,50|Alias:标题", // 自定义参数名称
]); // 抛出异常的错误描述为:“标题”长度必须在 2 - 50 之间

Validation::validate($params, [
    "title" => "Required|StrLenGeLe:2,50|>>>:标题长度应在2~50之间", // 自定义错误信息描述文本
]); // 抛出异常的错误描述为:标题长度应在2~50之间

参考附录A.10获取更详细的信息

4.15 国际化

从0.4版开始:

  • 使用新的静态成员变量 $langCode2ErrorTemplates 来进行“错误提示信息模版”的翻译,主要目的是简化格式(感谢 @gitHusband 的建议)。
  • 旧的翻译表 $langCodeToErrorTemplates 仍然有效,已有代码无需修改(参考下一节)。如果新旧翻译表同时提供,优先新的,新表中查不到再使用旧的。

要支持国际化,需要自定义一个类,继承\WebGeeker\Validation\Validation,重载两个静态成员变量:

  • $langCode2ErrorTemplates用于提供“错误提示信息模版”的翻译对照表。完整的错误提示信息模版列表可以在\WebGeeker\Validation\Validation::$errorTemplates成员变量中找到
  • $langCodeToTranslations用于提供“自定义参数名称”(由Alias指定)和“自定义错误描述文本”(由>>>指定)的翻译对照表。

下面提供一个示例类:

class MyValidation extends Validation
{
    // “错误提示信息模版”翻译对照表
    protected static $langCodeToErrorTemplates = [
        "zh-tw" => [
            'Int' => '“{{param}}”必須是整數', // 🌝
            'IntGt' => '“{{param}}”必須大於 {{min}}',
            'Str' => '“{{param}}”必須是字符串',
        ],
        "en-us" => [
            'Int' => '{{param}} must be an integer',
            'IntGt' => '{{param}} must be greater than {{min}}',
            'Str' => '{{param}} must be a string',
        ],
    ];

    // 文本翻译对照表
    protected static $langCodeToTranslations = [
        "zh-tw" => [
            "变量" => "變量", // 🌙
            "变量必须是整数" => "變量必須是整數", // ⭐
        ],
        "en-us" => [
            "变量" => "variable",
            "变量必须是整数" => "variable must be an integer",
        ],
    ];
}

注意:

  • 语言代码是区分大小写的,建议全部用小写,如"zh-cn", "en-us"等。
  • 语言代码的名称是自定义的,你可以随便起名,比如"abc"(建议使用标准的语言代码)。

使用这个MyValidation类来进行验证,就可以实现文本的翻译了。

MyValidation::setLangCode("zh-tw"); // 设置语言代码

MyValidation::validate(["var" => 1.0], [
    "var" => "Int", // 既没有Alias,也没有>>>,只会翻译错误提示信息模版(对应🌝那行)
]); // 会抛出异常:“var”必須是整數

MyValidation::validate(["var" => 1.0], [
    "var" => "Int|Alias:变量", // 有Alias,除了翻译错误提示信息模版外,还会翻译参数名称(对应🌙那行)
]); // 会抛出异常:“變量”必須是整數

MyValidation::validate(["var" => 1.0], [
    "var" => "Int|>>>:变量必须是整数", // 有>>>,会翻译自定义错误描述文本(对应⭐那行)
]); // 会抛出异常:變量必須是整數

如果提供了错误的语言代码,或者没有找到翻译的文本,那么就不翻译,输出原始的文本。

4.16 国际化(0.4版之前)

(如果你使用的是0.4及之后的版本,建议使用新的国际化方案(参考上一节),更简洁一点)

要支持国际化,需要自定义一个类,继承\WebGeeker\Validation\Validation,重载两个静态成员变量:

  • $langCodeToErrorTemplates用于提供“错误提示信息模版”的翻译对照表。完整的错误提示信息模版列表可以在\WebGeeker\Validation\Validation::$errorTemplates成员变量中找到
  • $langCodeToTranslations用于提供“自定义参数名称”(由Alias指定)和“自定义错误描述文本”(由>>>指定)的翻译对照表。

下面提供一个示例类:

class MyValidation extends Validation
{
    // “错误提示信息模版”翻译对照表
    protected static $langCodeToErrorTemplates = [
        "zh-tw" => [
            "“{{param}}”必须是整数" => "“{{param}}”必須是整數", // 🌝
            "“{{param}}”必须是字符串" => "“{{param}}”必須是字符串",
        ],
        "en-us" => [
            "“{{param}}”必须是整数" => "{{param}} must be a integer",
            "“{{param}}”必须是字符串" => "{{param}} must be a string",
        ],
    ];

    // 文本翻译对照表
    protected static $langCodeToTranslations = [
        "zh-tw" => [
            "变量" => "變量", // 🌙
            "变量必须是整数" => "變量必須是整數", // ⭐
        ],
        "en-us" => [
            "变量" => "variable",
            "变量必须是整数" => "variable must be an integer",
        ],
    ];
}

注意:

  • 语言代码是区分大小写的,建议全部用小写,如"zh-cn", "en-us"等。
  • 语言代码的名称是自定义的,你可以随便起名,比如"abc"(建议使用标准的语言代码)。

使用这个MyValidation类来进行验证,就可以实现文本的翻译了。

MyValidation::setLangCode("zh-tw"); // 设置语言代码

MyValidation::validate(["var" => 1.0], [
    "var" => "Int", // 既没有Alias,也没有>>>,只会翻译错误提示信息模版(对应🌝那行)
]); // 会抛出异常:“var”必須是整數

MyValidation::validate(["var" => 1.0], [
    "var" => "Int|Alias:变量", // 有Alias,除了翻译错误提示信息模版外,还会翻译参数名称(对应🌙那行)
]); // 会抛出异常:“變量”必須是整數

MyValidation::validate(["var" => 1.0], [
    "var" => "Int|>>>:变量必须是整数", // 有>>>,会翻译自定义错误描述文本(对应⭐那行)
]); // 会抛出异常:變量必須是整數

如果提供了错误的语言代码,或者没有找到翻译的文本,那么就不翻译,输出原始的文本。

A 附录 - 验证器列表

A.1 整型

整型验证器全部以"Int"开头。

整型验证器 示例 说明
Int Int “{{param}}”必须是整数
IntEq IntEq:100 “{{param}}”必须等于 {{value}}
IntGt IntGt:100 “{{param}}”必须大于 {{min}}
IntGe IntGe:100 “{{param}}”必须大于等于 {{min}}
IntLt IntLt:100 “{{param}}”必须小于 {{max}}
IntLe IntLe:100 “{{param}}”必须小于等于 {{max}}
IntGtLt IntGtLt:1,100 “{{param}}”必须大于 {{min}} 小于 {{max}}
IntGeLe IntGeLe:1,100 “{{param}}”必须大于等于 {{min}} 小于等于 {{max}}
IntGtLe IntGtLe:1,100 “{{param}}”必须大于 {{min}} 小于等于 {{max}}
IntGeLt IntGeLt:1,100 “{{param}}”必须大于等于 {{min}} 小于 {{max}}
IntIn IntIn:2,3,5,7,11 “{{param}}”只能取这些值: {{valueList}}
IntNotIn IntNotIn:2,3,5,7,11 “{{param}}”不能取这些值: {{valueList}}

A.2 浮点型

内部一律使用double来处理

浮点型验证器 示例 说明
Float Float “{{param}}”必须是浮点数
FloatGt FloatGt:1.0 “{{param}}”必须大于 {{min}}
FloatGe FloatGe:1.0 “{{param}}”必须大于等于 {{min}}
FloatLt FloatLt:1.0 “{{param}}”必须小于 {{max}}
FloatLe FloatLe:1.0 “{{param}}”必须小于等于 {{max}}
FloatGtLt FloatGtLt:0,1.0 “{{param}}”必须大于 {{min}} 小于 {{max}}
FloatGeLe FloatGeLe:0,1.0 “{{param}}”必须大于等于 {{min}} 小于等于 {{max}}
FloatGtLe FloatGtLe:0,1.0 “{{param}}”必须大于 {{min}} 小于等于 {{max}}
FloatGeLt FloatGeLt:0,1.0 “{{param}}”必须大于等于 {{min}} 小于 {{max}}

A.3 bool型

bool型验证器 示例 说明
Bool Bool 合法的取值为: true, false, "true", "false"(忽略大小写)
BoolSmart BoolSmart 合法的取值为: true, false, "true", "false", 1, 0, "1", "0", "yes", "no", "y", "n"(忽略大小写)

A.4 字符串型

字符串型验证器 示例 说明
Str Str “{{param}}”必须是字符串
StrEq StrEq:abc “{{param}}”必须等于"{{value}}"
StrEqI StrEqI:abc “{{param}}”必须等于"{{value}}"(忽略大小写)
StrNe StrNe:abc “{{param}}”不能等于"{{value}}"
StrNeI StrNeI:abc “{{param}}”不能等于"{{value}}"(忽略大小写)
StrIn StrIn:abc,def,g “{{param}}”只能取这些值: {{valueList}}
StrInI StrInI:abc,def,g “{{param}}”只能取这些值: {{valueList}}(忽略大小写)
StrNotIn StrNotIn:abc,def,g “{{param}}”不能取这些值: {{valueList}}
StrNotInI StrNotInI:abc,def,g “{{param}}”不能取这些值: {{valueList}}(忽略大小写)
StrLen StrLen:8 “{{param}}”长度必须等于 {{length}}
StrLenGe StrLenGe:8 “{{param}}”长度必须大于等于 {{min}}
StrLenLe StrLenLe:8 “{{param}}”长度必须小于等于 {{max}}
StrLenGeLe StrLenGeLe:6,8 “{{param}}”长度必须在 {{min}} - {{max}} 之间
ByteLen ByteLen:8 “{{param}}”长度(字节)必须等于 {{length}}
ByteLenGe ByteLenGe:8 “{{param}}”长度(字节)必须大于等于 {{min}}
ByteLenLe ByteLenLe:8 “{{param}}”长度(字节)必须小于等于 {{max}}
ByteLenGeLe ByteLenGeLe:6,8 “{{param}}”长度(字节)必须在 {{min}} - {{max}} 之间
Letters Letters “{{param}}”只能包含字母
Alphabet Alphabet 同Letters
Numbers Numbers “{{param}}”只能是纯数字
Digits Digits 同Numbers
LettersNumbers LettersNumbers “{{param}}”只能包含字母和数字
Numeric Numeric “{{param}}”必须是数值。一般用于大数处理(超过double表示范围的数,一般会用字符串来表示)(尚未实现大数处理), 如果是正常范围内的数, 可以使用'Int'或'Float'来检测
VarName VarName “{{param}}”只能包含字母、数字和下划线,并且以字母或下划线开头
Email Email “{{param}}”必须是合法的email
Url Url “{{param}}”必须是合法的Url地址
Ip Ip “{{param}}”必须是合法的IP地址
Mac Mac “{{param}}”必须是合法的MAC地址
Regexp Regexp:/^abc$/ Perl正则表达式匹配

A.5 数组型

数组型验证器 示例 说明
Arr Arr “{{param}}”必须是数组
ArrLen ArrLen:5 “{{param}}”数组长度必须等于 {{length}}
ArrLenGe ArrLenGe:1 “{{param}}”数组长度必须大于等于 {{min}}
ArrLenLe ArrLenLe:9 “{{param}}”数组长度必须小于等于 {{max}}
ArrLenGeLe ArrLenGeLe:1,9 “{{param}}”长数组度必须在 {{min}} ~ {{max}} 之间

A.6 对象型

对象型验证器 示例 说明
Obj Obj “{{param}}”必须是对象

A.7 文件型

文件型验证器 示例 说明
File File “{{param}}”必须是文件
FileMaxSize FileMaxSize:10mb “{{param}}”必须是文件, 且文件大小不超过{{size}}
FileMinSize FileMinSize:100kb “{{param}}”必须是文件, 且文件大小不小于{{size}}
FileImage FileImage “{{param}}”必须是图片
FileVideo FileVideo “{{param}}”必须是视频文件
FileAudio FileAudio “{{param}}”必须是音频文件
FileMimes FileMimes:mpeg,jpeg,png “{{param}}”必须是这些MIME类型的文件:{{mimes}}

A.8 日期和时间型

日期和时间型验证器 示例 说明
Date Date “{{param}}”必须符合日期格式YYYY-MM-DD
DateFrom DateFrom:2017-04-13 “{{param}}”不得早于 {{from}}
DateTo DateTo:2017-04-13 “{{param}}”不得晚于 {{to}}
DateFromTo DateFromTo:2017-04-13,2017-04-13 “{{param}}”必须在 {{from}} ~ {{to}} 之间
DateTime DateTime “{{param}}”必须符合日期时间格式YYYY-MM-DD HH:mm:ss
DateTimeFrom DateTimeFrom:2017-04-13 12:00:00 “{{param}}”不得早于 {{from}}
DateTimeTo DateTimeTo:2017-04-13 12:00:00 “{{param}}”必须早于 {{to}}
DateTimeFromTo DateTimeFromTo:2017-04-13 12:00:00,2017-04-13 12:00:00 “{{param}}”必须在 {{from}} ~ {{to}} 之间

A.9 条件判断型

在一条验证规则中,条件验证器必须在其它验证器前面,多个条件验证器可以串联。

注意,条件判断中的“条件”一般是检测另外一个参数的值,而当前参数的值是由串联在条件判断验证器后面的其它验证器来验证。

条件判断型验证器 示例 说明
If If:selected 如果参数"selected"值等于 1, true, '1', 'true', 'yes'或 'y'(字符串忽略大小写)
IfNot IfNot:selected 如果参数"selected"值等于 0, false, '0', 'false', 'no'或'n'(字符串忽略大小写)
IfTrue IfTrue:selected 如果参数"selected"值等于 true 或 'true'(忽略大小写)
IfFalse IfFalse:selected 如果参数"selected"值等于 false 或 'false'(忽略大小写)
IfExist IfExist:var 如果参数"var"存在
IfNotExist IfNotExist:var 如果参数"var"不存在
IfIntEq IfIntEq:var,1 if (var === 1)
IfIntNe IfIntNe:var,2 if (var !== 2). 特别要注意的是如果条件参数var的数据类型不匹配, 那么If条件是成立的; 而其它几个IfIntXx当条件参数var的数据类型不匹配时, If条件不成立
IfIntGt IfIntGt:var,0 if (var > 0)
IfIntLt IfIntLt:var,1 if (var < 0)
IfIntGe IfIntGe:var,6 if (var >= 6)
IfIntLe IfIntLe:var,8 if (var <= 8)
IfIntIn IfIntIn:var,2,3,5,7 if (in_array(var, [2,3,5,7]))
IfIntNotIn IfIntNotIn:var,2,3,5,7 if (!in_array(var, [2,3,5,7]))
IfStrEq IfStrEq:var,waiting if (var === 'waiting')
IfStrNe IfStrNe:var,editing if (var !== 'editing'). 特别要注意的是如果条件参数var的数据类型不匹配, 那么If条件是成立的; 而其它几个IfStrXx当条件参数var的数据类型不匹配时, If条件不成立
IfStrGt IfStrGt:var,a if (var > 'a')
IfStrLt IfStrLt:var,z if (var < 'z')
IfStrGe IfStrGe:var,A if (var >= '0')
IfStrLe IfStrLe:var,Z if (var <= '9')
IfStrIn IfStrIn:var,normal,warning,error if (in_array(var, ['normal', 'warning', 'error'], true))
IfStrNotIn IfStrNotIn:var,warning,error if (!in_array(var, ['warning', 'error'], true))

A.10 其它验证器

其它验证器 示例 说明
Required Required 待验证的参数是必需的。如果验证器串联,除了条件型验证器外,必须为第一个验证器
Alias Alias:参数名称 自定义错误提示文本中的参数名称(必须是最后一个验证器)
>>> >>>:这是自定义错误提示文本 自定义错误提示文本(与Alias验证器二选一,必须是最后一个验证器)
自定义PHP函数 function() {} 暂不提供该机制,因为如果遇到本工具不支持的复杂参数验证,你可以直接写PHP代码来验证,不需要再经由本工具来验证(否则就是脱裤子放屁,多此一举)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,114评论 0 13
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,858评论 6 13
  • 1 2016年8月29日,全中国的朋友圈被一句话给刷屏了,这...
    w王大铭阅读 403评论 0 0
  • 青海,给我的第一印象就是草原,连绵不断的山脉,在幽蓝的天穹与黛绿的草原间,一望无际,偶尔有像巨人矗立起来的山峰。 ...
    丝路花雨_a690阅读 178评论 0 1