Filter
<br/>
>i 本文档的最新修订日期是:
> **2024-02-28**
# Filter ::
# 模块简述
对数据进行校验。
# 模块配置
配置文件位于 <font color="#c7254e">`/config/core/Filter.php`</font> 。
* **<font color="#ff6600">`rule`</font>** <font color="#0099ff">`(Array)`</font> <font color="#bbbbbb">`~`</font> :
用以指定验证规则。
值为一个一维数组,数组中元素的 <font color="#c7254e">`键`</font> 为规则的名称(不可包含分隔符 <font color="#c7254e">`|`</font>),元素的<font color="#c7254e">`值`</font> 为正则表达式字符串。
本模块已内置了如下规则(重复定义无效):
::: hljs-center
|ip|mac|email|
|-|-|-|
|IP地址|MAC地址|邮箱地址|
|convert_type|
|-|
|按模板转换数据类型|
:::
同时还内置了以下规则(可修改):
* <font color="#c7254e">`domian`</font>:域名
* <font color="#c7254e">`url`</font>:URL
* <font color="#c7254e">`url_port`</font>:允许携带端口号的URL
* <font color="#c7254e">`price`</font>:价格(精确到分)
* <font color="#c7254e">`cn_mobile`</font>:中国大陆11位手机手机号
* <font color="#c7254e">`cn_phone`</font>:中国大陆固定电话(分机号请单独验证)
* <font color="#c7254e">`cn_idcard`</font>:中国大陆身份证号
* <font color="#c7254e">`cn_name`</font>:中国姓名(含少数民族姓名中的点符号)
* <font color="#c7254e">`cn_username`</font>:中文用户名&昵称
* <font color="#c7254e">`en_username`</font>:英文用户名&昵称
* <font color="#c7254e">`password`</font>:普通强度密码,必须含有字母、数字,其它字符仅限于以下字符之内:<font color="#c7254e">`_-+,.!$*()[]{};:<>#@&=`</font>
* <font color="#c7254e">`password+`</font>://中级强度密码,必须含有大写字母、小写字母、数字,其它字符仅限于以下字符之内:<font color="#c7254e">`_-+,.!$*()[]{};:<>#@&=`</font>
* <font color="#c7254e">`password++`</font>:高级强度密码,必须含有且仅限于大写字母、小写字母、数字、特殊字符,特殊字符仅限于以下字符之内:<font color="#c7254e">`_-+,.!$*()[]{};:<>#@&=`</font>
# 校验策略
校验策略是格式为 <font color="#c7254e">`数据类型[,最小长度/值] [,最大长度/值] [,校验规则]`</font> 的字符串。
* <font color="#c7254e">`数据类型`</font> :数据检测/转换时的目标数据类型。
||*|int|float|float\<n\>|bool|string|json|object|array|
|-|-|-|-|-|-|-|-|-|-|
|说明|任意类型|整形|浮点数|浮点数,精度为n|布尔型|字符串|JSON格式的字符串|对象|数组
|示例|*(1)|int (1)|float (0.3)|float5 (3.14159)|bool (true)|string ('hello')|json ('{"id":1}')|object ($a->b)|array ([1,3,5,7])
在不同的参数中,取值范围不同:
* 在 <font color="#c7254e">`field(字段)`</font> 参数中使用时,取值范围是:
<font color="#c7254e">`int|float|float<n>|bool|string|json|object|array`</font>
* 在 <font color="#c7254e">`template(模板)`</font> 参数内的 <font color="#c7254e">`__self`</font> 元素中使用时,取值范围是:
<font color="#c7254e">`object|array`</font>
* 在 <font color="#c7254e">`template(模板)`</font> 参数内的 <font color="#c7254e">`__key`</font> 元素中使用时,取值范围是:
<font color="#c7254e">`int|float|float<n>|string`</font>
* 在 <font color="#c7254e">`template(模板)`</font> 参数内的 <font color="#c7254e">`__default`</font> 元素中,或对象中的键(键对应的目标值非对象或数组)使用时,取值范围是:
<font color="#c7254e">`int|float|float<n>|string|bool|*`</font>
>i 在数据类型校验时,会将 <font color="#c7254e">`(int)N`</font> 与 <font color="#c7254e">`(float/float<n>)N.00`</font> 视作类型相等且值相等。
* <font color="#c7254e">`最小长度/值`</font> / <font color="#c7254e">`最大长度`</font> :数据的目标最小或最大长度/值。
取值为 <font color="#c7254e">`*`</font> 时,代表不限制。
* 当数据类型为 <font color="#c7254e">`int|float|float<n>`</font> 时,此处的值代表数值的最小(≤)或最大(≥)值。
* 当数据类型为 <font color="#c7254e">`string`</font> 时,此处的值代表字符串的最小(≤)或最大(≥)长度。
* 当数据类型为 <font color="#c7254e">`array|object`</font> 时,此处的值代表对象/数组内的最小(≤)或最大(≥)数量。
* 当数据类型为 <font color="#c7254e">`bool|json`</font> 时,此处的值无效,可取值为 <font color="#c7254e">`*`</font>。
* <font color="#c7254e">`校验规则`</font> 为模块配置项 <font color="#c7254e">`rule`</font> 中所定义的校验规则,或一个可选值的列表。
当数据类型为 <font color="#c7254e">`json|object|array`</font> 时,此处的值无效。
所有数据在校验时都会按 <font color="#c7254e">`string`</font> 类型进行校验。
如果希望待校验的数据必须为某几个值中的一个,则需要将多个值通过分隔符 <font color="#c7254e">`|`</font> 分开,例如:
```PHP
$Config = [
'字段' => [
'delete' => 'bool',
'mode' => 'string,0,0,default|default' //指定值必须为default
],
'模式' => 'POST'
];
$Form = \core\Filter::byMode($Config);
```
模块配置项 <font color="#c7254e">`rule`</font> 中已经提供了常用的校验规则。
# check()
## 说明
**<font color="#0099ff"><font color="#ff6600">Filter</font> :: <font color="#ff6600">check</font> ( <kbd>传参数组</kbd> )</font>**
对数据进行校验及转换。
此方法 <font color="#c7254e">`支持`</font> 中文参数名。
## 参数
* **<font color="#ff6600">`field(字段)`</font>** <font color="#0099ff">`(Array)`</font> <font color="#BBBBBB">`必须`</font>:
用以指定字段和校验规则。
此参数为一个一维数组,数组的键为 <font color="#c7254e">`字段名`</font> ,值为 <font color="#c7254e">`校验策略`</font> 。
* <font color="#c7254e">`字段名`</font> :需要检查的字段名称。
* <font color="#c7254e">`校验策略`</font> :请参阅本篇文档开头“校验策略”一节。
* **<font color="#ff6600">`optional(可选)`</font>** <font color="#0099ff">`(Array)`</font> <font color="#bbbbbb">`[]`</font>:
用以指定可选(非必须)的字段。
此参数为一个一维数组,数组的键无需定义,值为 <font color="#c7254e">`字段名`</font> 的字符串。
若某个字段在本参数数组元素内,则仅当该字段存在时才进行校验。
* **<font color="#ff6600">`mode(模式)`</font>** <font color="#0099ff">`(String)`</font> <font color="#bbbbbb">`必须`</font>:
用以指定数据的来源。
此参数的必须是空字符串或 <font color="#c7254e">`GET/POST/HEADER/COOKIE`</font> 中的一个。
* **<font color="#ff6600">`data(数据)`</font>** <font color="#0099ff">`(Array)`</font> <font color="#bbbbbb">`[]`</font>:
用以指定校验的数据。
仅当参数 <font color="#c7254e">`mode`</font> 传入的值为空字符串时,本参数才有效。
如果需要校验一个非数组值,需要先将其组成为数组。
* **<font color="#ff6600">`template(模板)`</font>** <font color="#0099ff">`(Array)`</font> <font color="#bbbbbb">`[]`</font>:
指定对象/数组/JSON字符串的校验规则。
此参数为一个一维数组,数组的键为 <font color="#c7254e">`字段名`</font> ,值为 <font color="#c7254e">`校验模板`</font> 。
<font color="#c7254e">`校验模板`</font> 是一个将对象转换为JSON格式的字符串,对象中的每一个元素的键与待校验数据的键对应。
如果目标元素的数据类型为 <font color="#c7254e">`Array|Object`</font> ,那么模板中该元素的数据类型为 <font color="#c7254e">`Object`</font> ,否则模板中该元素的值为 <font color="#c7254e">`校验策略`</font> 。
如果要为目标元素动态指定校验策略,则模板中该元素的值必须为字符串 <font color="#c7254e">`*`</font> 。
模板中的对象类型的元素可以包含如下特定键名的元素:
* <font color="#c7254e">`__self`</font> :可选,当前层级的数据校验策略。
值为 <font color="#c7254e">`校验策略`</font> 字符串。
当校验策略中的校验规则为 <font color="#c7254e">`convert_type`</font> 时,会将数据直接转换而不去比较(校验)数据类型。其它的校验规则在此处无效。
仅当当前层级存在 <font color="#c7254e">`__default`</font> 元素时,校验策略中的最大或最小长度/值才有效。
如果不存在此元素,则此元素将被自动填充为 <font color="#c7254e">`object,*,*`</font> 。
* <font color="#c7254e">`__key`</font> :可选,当前层级元素的键名的校验策略。
仅当当前层级存在 <font color="#c7254e">`__default`</font> 元素,并且当前层级不存在指定的键时,本元素才有效。
* <font color="#c7254e">`__default`</font> :可选,当前层级元素的键名的校验策略或模板。
值为 <font color="#c7254e">`校验策略`</font> 字符串,或一个模板对象。
仅当当前层级不存在指定的键时,本元素才有效。
* <font color="#c7254e">`__optional`</font> :可选,当前层级可选的元素列表。
值为一个一维数组,数组的键无需定义,值为 <font color="#c7254e">`键名`</font> 的字符串。
若某个键名在本参数数组元素内,则仅当该键名存在时才进行校验。
与 <font color="#c7254e">`Check()`</font> 方法中的 <font color="#c7254e">`optional(可选)`</font> 参数类似,可以理解为“允许待校验的数据中不存在指定的元素,但如果存在此元素,则需要按照规定的校验策略进行校验”。
* <font color="#c7254e">`__callback`</font> :可选,为当前层级的元素动态指定校验策略。
本元素为对象类型,键为 <font color="#c7254e">`键名`</font> 的字符串,值为 <font color="#c7254e">`callback(回调)`</font> 参数中存在的回调函数名称(即该参数中的键名)。
例如,如果预期的JSON如下:
```
{
"default": {
"id": -1,
"unicode": "",
"bar_code": [
//数组可以为空,但元素不能超过20个,且值为长度1~15的字符串。
],
"stock_position": ""
},
"list": [
{
"id": 781,
"unicode": "",
"bar_code": ["6927749801870"],
"stock_position": "",
"value": "鸡肉蔬菜",
"pic_token": "e00b7cdbc4b60d8225862a884852c4b7"
}, {
"id": 782,
"unicode": "",
"bar_code": ["6927749801894"],
"stock_position": "",
"value": "猪肉蔬菜",
"pic_token": "6f44b4777fe9ca9f99b91d82be7523e9"
}
],
"unit_type": "@qt",
"unit_id": 61
}
```
则对应的模板如下:
```
{
"default": {
"id": "int,-1",
"unicode": "string,0",
"bar_code": {
"__self": "array,0,20",
"__default": "string,1,15"
},
"stock_position": "string,0,20"
},
"list": {
"__default": {
"id": "int,-1",
"unicode": "string,0",
"bar_code": {
"__self": "array,0,20",
"__default": "string,1,15"
},
"stock_position": "string,0,20",
"value": "string,1,20",
"pic_token": "string,32,32",
"__optional": ["pic_token"]
},
"__self": "array,0,10"
},
"unit_type": "string,0,20",
"unit_id": "int,-1"
}
```
* **<font color="#ff6600">`return_object(返回对象)`</font>** <font color="#0099ff">`(Bool)`</font> <font color="#BBBBBB">`false`</font>:
用以指定将传入的JSON字符串/对象在返回时转换为对象还是数组。
当值为 <font color="#c7254e">`true`</font> 时转换为对象,值为 <font color="#c7254e">`false`</font> 时转换为对象数组。
## 返回
<font color="#0099ff">`(Bool|Array)`</font> 类型。
返回数组的键为字段名,值为经过校验及转换后的数据。
当校验未通过时返回 <font color="#c7254e">`false`</font> 。
## Hook
* **<font color="#ff6600">`apiphp_filter_check-failed`</font>** <font color="#0099ff">`/lib/core/Filter.php`</font> <font color="#bbbbbb">`无需返回`</font> :
当校验未通过时,在返回 <font color="#c7254e">`false`</font> 之前,于 <font color="#c7254e">`Filter::check()`</font> 中被调用。
传参数组中 <font color="#c7254e">`field`</font> 元素的值即为未通过校验的字段值。
传参数组中 <font color="#c7254e">`result`</font> 元素为一个一维数组,代表字段的校验结果明细,子元素的键为 <font color="#c7254e">`检测项目`</font>,子元素的值为 <font color="#c7254e">`true`</font> 时即为通过校验,值为 <font color="#c7254e">`false`</font> 时则为未通过校验。
如果传参数组中 <font color="#c7254e">`result`</font> 元素是一个空数组,则代表指定的字段不存在。
# lastCheck()
## 说明
**<font color="#0099ff"><font color="#ff6600">Filter</font> :: <font color="#ff6600">lastCheck</font> ( <kbd>传参数组</kbd> )</font>**
返回最后一次使用 <font color="#c7254e">`check()`</font> 方法校验数据的校验结果。
## 参数
无。
## 返回
<font color="#0099ff">`(Array)`</font> 类型。
* 数组中 <font color="#c7254e">`result`</font> 元素为一维数组,代表字段的校验结果明细,子元素的键为 <font color="#c7254e">`字段名`</font>,当子元素的值为 <font color="#c7254e">`true`</font> 时即为通过校验,值为 <font color="#c7254e">`false`</font> 时则为未通过校验。各子元素的含义如下:
* <font color="#c7254e">`exist`</font> :字段存在校验。
* <font color="#c7254e">`length`</font> :长度校验。
* <font color="#c7254e">`rule`</font> :规则校验。
* <font color="#c7254e">`json`</font> :JSON字符串解析结果。
* <font color="#c7254e">`object`</font> :对象校验。
* <font color="#c7254e">`object_key`</font> :校验结束(或校验失败)前最新校验的对象/数据的键名称。
* 数组中 <font color="#c7254e">`optional`</font> 元素为一维数组,代表可选的字段是否存在,子元素的键为 <font color="#c7254e">`字段名`</font>,当子元素的值为 <font color="#c7254e">`true`</font> 时存在该字段,值为 <font color="#c7254e">`false`</font> 时则为不存在该字段。
* 数组中 <font color="#c7254e">`mode`</font> 元素为字符串,代表本次校验时指定的 <font color="#c7254e">`mode`</font> 参数。当值为空字符串时,代表数据由 <font color="#c7254e">`data`</font> 参数传入。
>i 由于 <font color="#c7254e">`check()`</font> 遇到检验不通过的数据时会立即终止校验流程并返回 <font color="#c7254e">`false`</font>,因此本方法返回的数组中不一定包含完整的参数列表。