1. UML类图

点击查看【processon】

2. 方法详解

2.1 构造方法 __construct()

  • 参数:
  • 返回:
  • 源码:如下

    1. public function __construct()
    2. {
    3. //这里类的静态属性$maker是注入服务的数组,遍历执行这些回调函数,参数是当前validate对象
    4. if (!empty(static::$maker)) {
    5. foreach (static::$maker as $maker) {
    6. call_user_func($maker, $this);
    7. }
    8. }
    9. }
  • 说明:

  1. 对象在构造时会遍历 $maker (注入服务的闭包数组)的静态属性,通过call_user_func()执行,传递当前对象作为服务的参数。

    2.2 设置服务注入 maker() 方法

  • 参数:

[Closure](https://www.php.net/manual/zh/class.closure.php)``$maker 注入的服务

  • 返回:
  • 源码:如下
    1. public static function maker(Closure $maker)
    2. {
    3. static::$maker[] = $maker;
    4. }

2.3 设置语言对象 setLang() 方法

  • 参数:

Lang $lang 语言对象

  • 返回:
  • 源码:如下

    1. public function setLang(Lang $lang)
    2. {
    3. $this->lang = $lang;
    4. }

    2.4 设置Db对象 setDb() 方法

  • 参数:

Db $db Db对象

  • 返回:
  • 源码:如下 ```php public function setDb(Db $db)
    {
    1. $this->db = $db;
    }
  1. <a name="8IKf5"></a>
  2. #### 2.5 设置Request对象 `setRequest()` 方法
  3. - **参数:**
  4. `Request $request` 请求对象
  5. - **返回:**无
  6. - **源码:**如下
  7. ```php
  8. public function setRequest(Request $request)
  9. {
  10. $this->request = $request;
  11. }

2.6 添加字段验证规则 rule() 方法

  • 参数:

string|array $name 字段名称|规则数组
Closure|ValidateRule|string|array $rule 验证规则|字段描述信息

  • 返回:self
  • 源码:如下

    1. public function rule($name, $rule = '')
    2. {
    3. if (is_array($name)) {
    4. $this->rule = $name + $this->rule;
    5. if (is_array($rule)) {
    6. $this->field = array_merge($this->field, $rule);
    7. }
    8. } else {
    9. $this->rule[$name] = $rule;
    10. }
    11. return $this;
    12. }
  • 说明:

  1. 参数$name为数组的情况,表示操作为批量添加,操作会将对象的$rule属性和$name参数进行合并,$name将具有合并优先级, $name为字符串时是单一添加,操作会设置对象$rule属性数组的对应$name的索引的值为$rule
  2. 数组合并运算符 + 运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略,与array_merge()的区别是 + 运算符前面的数组有合并优先级,而array_merge()后面的数组有合并优先级;
  3. 参数$name $rule都为数组的情况,会将对象的$field(验证字段描述)属性和$rule参数进行合并, $rule参数将具有合并优先级;
  • 用法示例: ```php $validator = new Validate();

//第一种用法,批量设置字段age的验证规则为必须切不能超过25 $validator->rule([‘age’ => ‘require|max:25’]);

//第二种用法,同上设置单一字段的验证规则 $validator->rule(‘age’, ‘require|max:25’);

//第三种用法,批量设置字段age的验证规则为必须且不能超过25,并设置验证字段描述为’年龄’ $validator->rule([‘age’ => ‘require|max:25’], [‘age’ => ‘年龄’]);

//验证规则为闭包函数,闭包函数的value参数是验证字段的值,data参数是验证数组 $validator->rule(‘age’, function($value, $data){ return $value === 1 });

//验证规则为ValidateRule对象 $validator->rule(‘age’, new ValidateRule());

  1. <a name="uErR5"></a>
  2. #### 2.7 注册验证(类型)规则 `extend()` 方法
  3. - **参数:**
  4. `string $type` 验证规则类型<br />`callable $callback` callback方法(或闭包)<br />`string $message` 验证失败提示信息
  5. - **返回:**`self`
  6. - **源码:**如下
  7. ```php
  8. public function extend(string $type, callable $callback = null, string $message = null)
  9. {
  10. $this->type[$type] = $callback;
  11. if ($message) {
  12. $this->typeMsg[$type] = $message;
  13. }
  14. return $this;
  15. }
  • 说明:
  1. 对象的 $type 自定义验证类型属性会添加以参数 $type 作为索引以参数 $callback 作为值得数组项,如果有参数 $message 那么会在 $typeMsg (默认规则提示)属性添加以参数 $type 索引值为 $message 的数组项;
  2. $callback 代表的函数可接受$value(字段的值), $rule(通常为验证规则:后的值), $data(需验证的数组), $field(验证的字段), $title(验证字段描述)。
  • 用法示例: ```php $validator = new Validate();

//设置自定义验证规则captcha和对应的默认规则提示 function captcha_validate_callback($value, $rule, $data, $field, $title) { … } $validator->extend(‘captcha’, ‘capthca_validate_callback’, ‘:attribute not valid’);

//设置自定义验证规格为类的静态函数 $validator->extend(‘captcha’, ‘SomeClass::someMethod’);

//设置自定义验证规则为对象的方法 $validator->extend(‘captcha’, [$object, ‘someMethod’]);

//设置自定义验证规则为匿名函数 $validator->extend(‘captcha’, function(){ … });

  1. <a name="vohyN"></a>
  2. #### 2.8 设置验证(类型)规则的默认提示信息 `setTypeMsg()` 方法
  3. - **参数:**
  4. `string|array $type` 验证规则类型<br />`string $msg` 验证失败提示信息
  5. - **返回:**`self`
  6. - **源码:**如下
  7. ```php
  8. public function setTypeMsg($type, string $msg = null): void
  9. {
  10. if (is_array($type)) {
  11. $this->typeMsg = array_merge($this->typeMsg, $type);
  12. } else {
  13. $this->typeMsg[$type] = $msg;
  14. }
  15. }
  • 说明:
  1. $type 参数为数组进行批量设置,$type参数为字符串为单一设置;
  • 用法示例: ```php $validator = new Validate();

//批量设置 $validator->setTypeMsg([‘captcha’ => ‘:attribute not a valid captcha’]);

//单一设置 $validator->setTypeMsg(‘captcha’, ‘:attribute not a valid captcha’);

  1. <a name="P9DwQ"></a>
  2. #### 2.9 设置提示信息 `message()` 方法
  3. - **参数:**
  4. `array $msg` 错误信息
  5. - **返回:**`self`
  6. - **源码:**如下
  7. ```php
  8. public function message(array $message)
  9. {
  10. $this->message = array_merge($this->message, $message);
  11. return $this;
  12. }
  • 说明:
  1. $message属性和$typeMsg属性之间的区别:没有$message才会显示$typeMsg定义的提示信息;$typeMsg会经过编译取代变量;
  2. 错误信息可以通过属性定义和方法定义。

用法示例:

  1. $validator = new Validate();
  2. $validator->message(['name.require' => '姓名必须']);

2.10 设置当前验证场景 scene() 方法

  • 参数:

string $name 错误信息

  • 返回:self
  • 源码:如下

    1. public function scene(string $name)
    2. {
    3. $this->currentScene = $name;
    4. return $this;
    5. }
  • 说明:

  1. 设置的时$currentScene(当前验证场景)属性。

    2.11 判断验证场景是否已定义 hasScene() 方法

  • 参数:

string $name 错误信息

  • 返回:bool
  • 源码:如下

    1. public function hasScene(string $name): bool
    2. {
    3. return isset($this->scene[$name]) || method_exists($this, 'scene' . $name);
    4. }
  • 说明:

  1. 场景定义的方法: 可以通过类的属性 $scene 也可以通过定义方法sceneXXX()定义, 如下:

    1. class User extends Validate
    2. {
    3. protected $rule = [
    4. 'name' => 'require|max:25',
    5. 'age' => 'number|between:1,120',
    6. 'email' => 'email',
    7. ];
    8. protected $message = [
    9. 'name.require' => '名称必须',
    10. 'name.max' => '名称最多不能超过25个字符',
    11. 'age.number' => '年龄必须是数字',
    12. 'age.between' => '年龄只能在1-120之间',
    13. 'email' => '邮箱格式错误',
    14. ];
    15. //第一种方法,定义类的属性
    16. protected $scene = [
    17. 'edit' => ['name','age'],
    18. ];
    19. //第二种方法,定义类的方法
    20. public function sceneEdit()
    21. {
    22. return $this->only(['name','age'])
    23. ->append('name', 'min:5')
    24. ->remove('age', 'between')
    25. ->append('age', 'require|max:100');
    26. }
    27. }

    2.12 设置验证方式是批量验证 batch() 方法

  • 参数:无
  • 返回:self
  • 源码:如下 ```php public function batch(bool $batch = true) { $this->batch = $batch;
    return $this; }
  1. - **说明:**
  2. 1. 默认情况下,一旦有某个数据的验证规则不符合,就会停止后续数据及规则的验证,批量验证会完成后续数据及规则的验证;
  3. <a name="O34xM"></a>
  4. #### 2.13 设置验证失败后是否抛出异常 `failException()` 方法
  5. - **参数:**
  6. `bool $fail` 是否抛出异常
  7. - **返回:**`self`
  8. - **源码:**如下
  9. ```php
  10. public function failException(bool $fail = true)
  11. {
  12. $this->failException = $fail;
  13. return $this;
  14. }
  • 说明:
  1. 默认情况check()结果是通过函数返回值的方式返回的,设置了$failException属性,验证失败直接抛出ValidateException异常;

    2.14 指定需要验证的字段列表 only() 方法

  • 参数:

array $fields 字段名

  • 返回:self
  • 源码:如下 ```php public function only(array $fields) { $this->only = $fields;
    return $this; }
  1. - **说明:**
  2. 1. 对象设置了`$only`属性,进行验证时只验证`$only`属性指定的字段;
  3. <a name="2HTEv"></a>
  4. #### 2.15 移除某个字段的验证规则 `remove()` 方法
  5. - **参数:**
  6. `string|array $field` 字段名<br />`Closure|ValidateRule|array|string|true $rule` 验证规则
  7. - **返回:**`self`
  8. - **源码:**如下
  9. ```php
  10. public function remove($field, $rule = null)
  11. {
  12. if (is_array($field)) {
  13. foreach ($field as $key => $rule) {
  14. if (is_int($key)) {
  15. $this->remove($rule);
  16. } else {
  17. $this->remove($key, $rule);
  18. }
  19. }
  20. } else {
  21. if (is_string($rule)) {
  22. $rule = explode('|', $rule);
  23. }
  24. $this->remove[$field] = $rule;
  25. }
  26. return $this;
  27. }
  • 说明:
  1. 这个方法不是将对象的$rule属性中对应的规则删除,只是在$remove属性中标记不需要验证的规则;
  2. $field参数是数组时使用了递归的方法;
  3. $validator->remove('field', 'rule1')->remove('field', 'rule2')这种方式不成功,应该用$validator->remove('field', 'rule1|rule2')或者$validator->remove('field', ['rule1', 'rule2'])的方式;
  4. $rule参数为true时移除所有规则;
  • 用法示例: ```php $validator = new Validate();

//第一种,$field是字符串,$rule是数组,$remove=[‘field’ => [‘rule1’, ‘rule2’]] $validator->remove(‘field’, [‘rule1’,’rule2’]);

//第二种,$field是字符串,$rule是用|符号分割的字符串, $remove=[‘field’ => [‘rule1’, ‘rule2’]] $validator->remove(‘field’, ‘rule1|rule2’);

//第三种,$field是普通数组, $remove = [‘field1’ => null, ‘fidle2’ => null] $validator->remove([‘field1’, ‘field2’]);

//第四种,$field是关联数组, $remove = [‘field1’ => [‘rule1’, ‘rule2’], ‘field2’ => [‘rule3’, ‘rule4’]] $validator->remove([‘field1’ => ‘rule1|rule2’, ‘field2’ => [‘rule3’, ‘rule4’]]);

//第五种,$rule参数为true,移除所有规则, $remove = [‘field’ => true] $validator->remove(‘field’, true);

  1. <a name="LWBxQ"></a>
  2. #### 2.16 追加某个字段的验证规则 `append()` 方法
  3. - **参数:**
  4. `string|array $field` 字段名<br />`Closure|ValidateRule|array|string $rule` 验证规则
  5. - **返回:**`self`
  6. - **源码:**如下
  7. ```php
  8. public function append($field, $rule = null)
  9. {
  10. if (is_array($field)) {
  11. foreach ($field as $key => $rule) {
  12. $this->append($key, $rule);
  13. }
  14. } else {
  15. if (is_string($rule)) {
  16. $rule = explode('|', $rule);
  17. }
  18. $this->append[$field] = $rule;
  19. }
  20. return $this;
  21. }
  • 说明:
  1. 这个方法不是将对象的$rule属性中添加对应的规则,只是在$append属性中标记追加的验证的规则;
  2. $field参数是数组时使用了递归的方法;
  • 用法示例: ```php $validator = new Validate(); //第一种,$field是字符串,$rule是数组, $append = [‘field’ => [‘rule1’, ‘rule2’]] $validator->append(‘field’, [‘rule1’,’rule2’]);

//第二种,$field是字符串,$rule是用|符号分割的字符串,$append = [‘field’ => [‘rule1’, ‘rule2’]] $validator->append(‘field’, ‘rule1|rule2’);

//第三种,$field是关联数组, $append = [‘field1’ => [‘rule1’, ‘rule2’]]; $validator->append([‘field1’ => ‘rule1|rule2’]);

  1. <a name="9xgxH"></a>
  2. #### 2.17 自动验证 `check()` 方法
  3. - **参数:**
  4. `array $data` 待验证数据<br />`array $rules` 验证规则数组
  5. - **返回:**`bool`
  6. - **源码:**如下
  7. ```php
  8. public function check(array $data, array $rules = []): bool
  9. {
  10. //清空验证失败错误信息数组
  11. $this->error = [];
  12. //$rules参数为空的时候,验证规则采用对象$rule属性,否则验证规则采用参数
  13. if (empty($rules)) {
  14. //读取验证规则
  15. $rules = $this->rule;
  16. }
  17. //根据验证当前验证场景设置当前对象的$only $append $remove属性
  18. if ($this->currentScene) {
  19. $this->getScene($this->currentScene);
  20. }
  21. //将$append中的验证规则添加到$rule属性中,$append的验证规则优先级是低于$rule的
  22. //$rule属性字段的验证规则,$append会被忽略
  23. foreach ($this->append as $key => $rule) {
  24. if (!isset($rules[$key])) {
  25. $rules[$key] = $rule;
  26. }
  27. }
  28. //遍历验证规则属性$rule
  29. foreach ($rules as $key => $rule) {
  30. //'field' => 'rule1|rule2...'
  31. //'field' => ['rule1','rule2',...]
  32. //'age|年龄' => 'number|between:1,120'
  33. if (strpos($key, '|')) {
  34. //字段|描述 用于指定属性名称
  35. list($key, $title) = explode('|', $key);
  36. } else {
  37. $title = $this->field[$key] ?? $key;
  38. }
  39. //场景检测,只有设置了only并且当前字段不在only数组中,跳出遍历
  40. if (!empty($this->only) && !in_array($key, $this->only)) {
  41. continue;
  42. }
  43. //获取数据 支持二维数组
  44. $value = $this->getDataValue($data, $key);
  45. //字段验证
  46. //rule是闭包函数,执行闭包函数带参数value和data
  47. if ($rule instanceof Closure) {
  48. $result = call_user_func_array($rule, [$value, $data]);
  49. //rule是ValidateRule对象
  50. } elseif ($rule instanceof ValidateRule) {
  51. //验证因子
  52. $result = $this->checkItem($key, $value, $rule->getRule(), $data, $rule->getTitle() ?: $title, $rule->getMsg());
  53. //rule是数组或者字符串
  54. } else {
  55. $result = $this->checkItem($key, $value, $rule, $data, $title);
  56. }
  57. //验证失败
  58. if (true !== $result) {
  59. //没有返回true 则表示验证失败
  60. if (!empty($this->batch)) {
  61. //批量验证
  62. $this->error[$key] = $result;
  63. //不是批量验证直接抛出异常或者停止后续验证返回false
  64. } elseif ($this->failException) {
  65. throw new ValidateException($result);
  66. } else {
  67. $this->error = $result;
  68. return false;
  69. }
  70. }
  71. }
  72. //循环结束
  73. if (!empty($this->error)) {
  74. if ($this->failException) {
  75. throw new ValidateException($this->error);
  76. }
  77. return false;
  78. }
  79. return true;
  80. }
  • 说明:
  1. 如果通过scene()方法设置了$currentScene属性,同时在对象中设置的$append $only $remove属性将会清空,按$scene属性或sceneXXX()方法的定义设置$append $only $remove属性,结论就是scene() append() only() remove()方法不要在对象上同时使用,append() only() remove()方法在场景定义方法sceneXXX()中使用;
  2. check($data, array $rules)接收第二个参数$rule,有第二个参数的时候,类中定义的$rules属性将不起作用;
  3. 支持多维数组;
  4. $rule属性为$key => $value数组,$value可以是字符串 如'require|max:20', 可以是数组 如['require', 'max' => 20],可以是闭包函数,如function($value){return $value===1 ? true : false},还可以是ValidateRule对象,如ValidateRule::isRequire()->max(20);闭包函数通过call_user_func_array($rule, [$value, $data])执行,ValidateRule对象通过checkItem($key, $value, $validateRule->getRule(), $data, $title)执行。
  • 用法示例: ```php $validator = new Validate(); //说明1 示例 $validator->scene(‘edit’)
    1. //only remove append将不起作用
    2. ->only(['name', 'age'])
    3. ->remove('sex', 'rule1|rule2')
    4. ->append('score', 'rule3|rule4')
    5. ->check($data);

//说明2 示例 验证规则仅仅是check的参数$rules $validator->check($data, [‘name’ => ‘rule1|rule2’]);

//说明3 示例 多维数组的验证 $validator->check( [ ‘rule1’ => [‘rule2’ => 13], ], [ ‘rule1.rule2’ => ‘require|max:20’ ] )

  1. <a name="rk3Hx"></a>
  2. #### 2.18 根据验证规则验证数据 `checkRule()` 方法
  3. - **参数:**
  4. `mixed $value` 待验证数据<br />`Closure|ValidateRule|array|string $rules` 验证规则数组
  5. - **返回:**`bool`
  6. - **源码:**如下
  7. ```php
  8. public function checkRule($value, $rules): bool
  9. {
  10. //$rules是闭包函数直接执行
  11. if ($rules instanceof Closure) {
  12. return call_user_func_array($rules, [$value]);
  13. //$rules是ValiateRule对象,调用对象方法getRule()返回规则数组
  14. } elseif ($rules instanceof ValidateRule) {
  15. $rules = $rules->getRule();
  16. //$rules是字符串,转换为数组
  17. } elseif (is_string($rules)) {
  18. $rules = explode('|', $rules);
  19. }
  20. //遍历$rules数组
  21. foreach ($rules as $key => $rule) {
  22. //单个$rule是闭包
  23. if ($rule instanceof Closure) {
  24. $result = call_user_func_array($rule, [$value]);
  25. } else {
  26. //判断验证类型
  27. list($type, $rule) = $this->getValidateType($key, $rule);
  28. //有自定义的验证(类型)规则用自定的验证(类型)规则,否则用Validate的内置规则
  29. $callback = $this->type[$type] ?? [$this, $type];
  30. $result = call_user_func_array($callback, [$value, $rule]);
  31. }
  32. //验证失败
  33. if (true !== $result) {
  34. if ($this->failException) {
  35. throw new ValidateException($result);
  36. }
  37. return $result;
  38. }
  39. }
  40. return true;
  41. }
  • 说明:
  1. check()方法与checkRule()方法的比较不同之处:一,check()可以省略$rules参数,用对象的属性$rule进行验证,而checkRule()不可以省略$rules参数,二、check()可以进行批量验证,checkRule()不可以
  2. checkRule()更适合自由度高的验证;
  • 用法示例:

    1. $validator = new Validate();
    2. $validator->checkRule(['age' => 13], '['age' => 'between:1-100']');
    3. //或者
    4. $validator->checkRule(12, 'require|between:1-100');

    2.19 验证单个字段规则 checkItem() 方法

  • 参数:

string $field 字段名
mixed $value 字段值
array|string $rules 验证规则
array $data 验证数据
string $title 字段描述
array $msg 提示信息

  • 返回:bool
  • 源码:如下

    1. protected function checkItem(string $field, $value, $rules, $data, string $title = '', array $msg = [])
    2. {
    3. if (isset($this->remove[$field]) && true === $this->remove[$field] && empty($this->append[$field])) {
    4. //字段已经移除 无需验证
    5. return true;
    6. }
    7. //支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...]
    8. if (is_string($rules)) {
    9. $rules = explode('|', $rules);
    10. }
    11. if (isset($this->append[$field])) {
    12. //追加额外的验证规则
    13. $rules = array_unique(array_merge($rules, $this->append[$field]), SORT_REGULAR);
    14. }
    15. $i = 0;
    16. foreach ($rules as $key => $rule) {
    17. if ($rule instanceof Closure) {
    18. $result = call_user_func_array($rule, [$value, $data]);
    19. $info = is_numeric($key) ? '' : $key;
    20. } else {
    21. //判断验证类型
    22. list($type, $rule, $info) = $this->getValidateType($key, $rule);
    23. if (isset($this->append[$field]) && in_array($info, $this->append[$field])) {
    24. } elseif (isset($this->remove[$field]) && in_array($info, $this->remove[$field])) {
    25. // 规则已经移除
    26. $i++;
    27. continue;
    28. }
    29. if (isset($this->type[$type])) {
    30. $result = call_user_func_array($this->type[$type], [$value, $rule, $data, $field, $title]);
    31. } elseif ('must' == $info || 0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) {
    32. $result = call_user_func_array([$this, $type], [$value, $rule, $data, $field, $title]);
    33. } else {
    34. $result = true;
    35. }
    36. }
    37. if (false === $result) {
    38. //验证失败 返回错误信息
    39. if (!empty($msg[$i])) {
    40. $message = $msg[$i];
    41. if (is_string($message) && strpos($message, '{%') === 0) {
    42. $message = $this->lang->get(substr($message, 2, -1));
    43. }
    44. } else {
    45. $message = $this->getRuleMsg($field, $title, $info, $rule);
    46. }
    47. return $message;
    48. } elseif (true !== $result) {
    49. // 返回自定义错误信息
    50. if (is_string($result) && false !== strpos($result, ':')) {
    51. $result = str_replace(':attribute', $title, $result);
    52. if (strpos($result, ':rule') && is_scalar($rule)) {
    53. $result = str_replace(':rule', (string) $rule, $result);
    54. }
    55. }
    56. return $result;
    57. }
    58. $i++;
    59. }
    60. return $result;
    61. }

    2.20 获取当前验证类型及规则 getValidateType() 方法

  • 参数:

mixed $key $rules数组键
mixed $rule $rules数组值

  • 返回:array
  • 源码:如下 ```php protected function getValidateType($key, $rule): array {
    //判断验证类型,如[‘>=’ => 10],将返回[‘egt’, ‘10’, ‘egt’] if (!is_numeric($key)) {

    1. if (isset($this->alias[$key])) {
    2. // 判断别名
    3. $key = $this->alias[$key];
    4. }
    5. return [$key, $rule, $key];

    }

    1. //如[0 => '>=:10'],将返回['egt', '10', 'egt']

    if (strpos($rule, ‘:’)) {

    1. list($type, $rule) = explode(':', $rule, 2);
    2. if (isset($this->alias[$type])) {
    3. // 判断别名
    4. $type = $this->alias[$type];
    5. }
    6. $info = $type;
    7. //如[0 => 'ip'], 将返回['ip', '', 'ip']

    } elseif (method_exists($this, $rule)) {

    1. $type = $rule;
    2. $info = $rule;
    3. $rule = '';
    4. //如[0 => 'accepted'], 将返回['is', 'accepted', 'is']

    } else {

    1. $type = 'is';
    2. $info = $rule;

    }

    return [$type, $rule, $info]; }

  1. - **说明:**
  2. 1. `getValidateType(0, 'require')` 返回 `['is', 'require', 'is']`;
  3. 1. `getValidateType('max', 25)` 返回`['max', 25, 'max']`;
  4. 1. `getValidateType('same' 25)` 返回`['eq', 25, 'eq']`;
  5. 1. `getValidateType(0, 'max:25')` 返回`['max', 25, 'max']`;
  6. 1. `getValidateType(1, '=:25')` 返回`['eq', 25, 'eq']`
  7. 1. `getValidateType(1, 'confirm:pwd')` 返回`['confirm', 'pwd', 'confirm']`
  8. <a name="MNN2V"></a>
  9. #### 2.21 获取数据验证的场景 `getScene()` 方法
  10. - **参数:**
  11. `string $scene` 验证场景
  12. - **返回:**无
  13. - **源码:**如下
  14. ```php
  15. protected function getScene(string $scene): void
  16. {
  17. $this->only = $this->append = $this->remove = [];
  18. if (method_exists($this, 'scene' . $scene)) {
  19. call_user_func([$this, 'scene' . $scene]);
  20. } elseif (isset($this->scene[$scene])) {
  21. // 如果设置了验证适用场景
  22. $this->only = $this->scene[$scene];
  23. }
  24. }
  • 说明:
  1. getScene()方法会清空对象的$only $remove $append属性;
  2. 方法会根据sceneXXX()方法重新定义$only $remove $append属性;
  3. 方法会根据对象$scene属性定义$only属性;
  4. 场景方法定义sceneXXX()优先级高于属性定义$scene

    2.22 获取数据值 getDataValue() 方法

  • 参数:

array $data 数据
string $key 数据标识

  • 返回:mixed
  • 源码:如下

    1. protected function getDataValue(array $data, $key)
    2. {
    3. //如: getDataValue($data, '23') 将返回23
    4. if (is_numeric($key)) {
    5. $value = $key;
    6. //如: getDataValue(['key1' => ['key2' => 23]], 'key1.key2')将返回23
    7. } elseif (is_string($key) && strpos($key, '.')) {
    8. // 支持多维数组验证
    9. foreach (explode('.', $key) as $key) {
    10. if (!isset($data[$key])) {
    11. $value = null;
    12. break;
    13. }
    14. $value = $data = $data[$key];
    15. }
    16. } else {
    17. $value = $data[$key] ?? null;
    18. }
    19. return $value;
    20. }
  • 说明:

  1. getDataValue(['apple'], 1)返回的是1,这有什么用处?这是像egt:25这样的规则,type会是egtrule会是25,info会是egt,在egt函数中会调用getDataValue($data, 25),这个时候值在规则中已经定好,不需要从指定字段取值;
  2. getDataValue(['key1' => ['key2' => 'value']], 'key1.key2')返回value
  3. 不存在返回null

    2.23 验证是否和某个字段的值一致 confirm() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据
string $field 字段名

  • 返回:bool
  • 源码:如下

    1. public function confirm($value, $rule, array $data = [], string $field = ''): bool
    2. {
    3. if ('' == $rule) {
    4. if (strpos($field, '_confirm')) {
    5. $rule = strstr($field, '_confirm', true);
    6. } else {
    7. $rule = $field . '_confirm';
    8. }
    9. }
    10. return $this->getDataValue($data, $rule) === $value;
    11. }
  • 说明:

  1. $rule = ['pwd|密码' => 'require|confirm:repwd']这样的验证规则要check()时会调用checkItem('pwd', 密码值, $rule, $data, '密码')checkItem再将$rule分解为数组['require', 'confirm:repwd']遍历规则,遍历到confirm:repwd 会分解成[type, rule, info] 就是['confirm', 'repwd', 'confirm']调用此函数confirm(密码值, 'repwd', $data, 'pwd');
  2. rule为空代表的时rule规则不带:冒号后的内容,自动匹配验证规则,要验证的字段为a, 会去和confirm_a字段进行比较;要验证的字段为confirm_a,会去和a字段进行比较;
  3. strstr($haystack, $needle, $before_needel)返回 haystack 字符串从 needle 第一次出现的位置开始到 haystack 结尾的字符串,before_needle若为 truestrstr() 将返回 needlehaystack 中的位置之前的部分;
  4. 规则可写为confirm:field confirm

    2.24 验证是否和某个字段的值是否不同 different() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function different($value, $rule, array $data = []): bool
    2. {
    3. return $this->getDataValue($data, $rule) != $value;
    4. }
  • 说明:

  1. $rule=['field' => 'different:field2'] 会调用different(field的值, 'field2', $data)
  2. 规则可写为different:field different:30

    2.25 验证是否大于等于某个值 egt() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function egt($value, $rule, array $data = []): bool
    2. {
    3. return $value >= $this->getDataValue($data, $rule);
    4. }
  • 说明:

  1. 规则可以是egt:field egt:60或者>=:60

    2.26 验证是否大于某个值 gt() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function gt($value, $rule, array $data = []): bool
    2. {
    3. return $value > $this->getDataValue($data, $rule);
    4. }
  • 说明:

  1. 规则可以是gt:field gt:60 或者>:60

    2.27 验证是否小于等于某个值 elt() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function elt($value, $rule, array $data = []): bool
    2. {
    3. return $value <= $this->getDataValue($data, $rule);
    4. }
  • 说明:

  1. 规则可以是elt:field elt:60或者<=:60

    2.28 验证是否小于某个值 lt() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function lt($value, $rule, array $data = []): bool
    2. {
    3. return $value < $this->getDataValue($data, $rule);
    4. }
  • 说明:

  1. 规则可以是lt:field lt:60或者<:60

    2.29 验证是否等于某个值 eq() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function eq($value, $rule): bool
    2. {
    3. return $value == $rule;
    4. }
  • 说明:

  1. 规则可以是eq:60 =:60 same:60后面只能是值,不能是字段名称;

    2.30 必须验证 must() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function must($value, $rule = null): bool
    2. {
    3. return !empty($value) || '0' == $value;
    4. }
  • 说明:

  1. 规则可以是must

    2.31 验证字段是否是有效格式is()方法

  • 参数:

mixed $value 字段的值
string $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function is($value, string $rule, array $data = []): bool
    2. {
    3. switch (Str::camel($rule)) {
    4. case 'require':
    5. // 必须
    6. $result = !empty($value) || '0' == $value;
    7. break;
    8. case 'accepted':
    9. // 接受
    10. $result = in_array($value, ['1', 'on', 'yes']);
    11. break;
    12. case 'date':
    13. // 是否是一个有效日期
    14. $result = false !== strtotime($value);
    15. break;
    16. case 'activeUrl':
    17. // 是否为有效的网址
    18. $result = checkdnsrr($value);
    19. break;
    20. case 'boolean':
    21. case 'bool':
    22. // 是否为布尔值
    23. $result = in_array($value, [true, false, 0, 1, '0', '1'], true);
    24. break;
    25. case 'number':
    26. $result = ctype_digit((string) $value);
    27. break;
    28. case 'alphaNum':
    29. $result = ctype_alnum($value);
    30. break;
    31. case 'array':
    32. // 是否为数组
    33. $result = is_array($value);
    34. break;
    35. case 'file':
    36. $result = $value instanceof File;
    37. break;
    38. case 'image':
    39. $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]);
    40. break;
    41. case 'token':
    42. $result = $this->token($value, '__token__', $data);
    43. break;
    44. default:
    45. if (isset($this->type[$rule])) {
    46. // 注册的验证规则
    47. $result = call_user_func_array($this->type[$rule], [$value]);
    48. } elseif (function_exists('ctype_' . $rule)) {
    49. // ctype验证规则
    50. $ctypeFun = 'ctype_' . $rule;
    51. $result = $ctypeFun($value);
    52. } elseif (isset($this->filter[$rule])) {
    53. // Filter_var验证规则
    54. $result = $this->filter($value, $this->filter[$rule]);
    55. } else {
    56. // 正则验证
    57. $result = $this->regex($value, $rule);
    58. }
    59. }
    60. return $result;
    61. }
  • 说明

  1. require: value不能是"",null,undefined,array()
  2. accepted: value只能是 '1', 'on', 'yes'
  3. date: value是能strtotime()函数接收的日期时间格式
  4. activeUrl: value会用checkdnsrr()函数进行域名或ip的dns检测;
  5. boolbooleanvalue的值和类型要匹配true,false, 0, 1, '0', '1'
  6. number: value的值会转换为字符串用用ctype_digit()进行检测,注意"12.31",检测会是false,因为.的原因;
  7. alphaNum: value的值会用ctype_alnum()进行检测, [A-Za-z0-9]
  8. array: value的会用is_array()进行检测;
  9. file: 判断value的值是否是think\File类的实例;
  10. image: [1,2,3,6]代表的是[gif, jpeg, png, bmp]value的值是think\File类的实例;
  11. token:表单令牌的验证,会交给RequestcheckToken方法完成;
  12. 可以通过$type属性注册自定义的类型;
  13. alpha对应ctype_alpha
  14. cntrl对应ctype_antrl
  15. digit对应ctype_digit
  16. graph对应ctype_graph,是可打印(显示)字符检测,不包括空格;
  17. lower对应ctype_lower,小写字符检测;
  18. print对应ctype_print,是可打印(显示)字符检测,包括空格;
  19. punct对应ctype_punct,可打印的标点符号
  20. space对应ctype_space,除了空白字符,还包括缩进,垂直制表符,换行符,回车和换页字符;
  21. upper对应ctype_upper,大写字符检测;
  22. xdigit对应ctype_xdigit,十六进制字符串[A-Fa-f0-9]
  23. filter_var验证: 包括email ip integer url macAddr float
  24. 正则验证regex:\d{6}

    2.32 判断图像类型 getImageType() 方法

  • 参数:

string $image 图像路径

  • 返回:false|int
  • 源码:如下

    1. protected function getImageType($image)
    2. {
    3. if (function_exists('exif_imagetype')) {
    4. return exif_imagetype($image);
    5. }
    6. try {
    7. $info = getimagesize($image);
    8. return $info ? $info[2] : false;
    9. } catch (\Exception $e) {
    10. return false;
    11. }
    12. }
  • 说明:

  1. exif_imagetype() 通过读取一个图像的第一个字节并检查其签名,并返回图像类型;
  2. getimagesize()返回图像信息,索引2是图像类型的标记和exif_imagetype()相同,exif_imagetype更快;

    2.33 验证表单令牌 token() 方法

  • 参数:

mixed $value 字段的值
string $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function token($value, string $rule, array $data): bool
    2. {
    3. $rule = !empty($rule) ? $rule : '__token__';
    4. return $this->request->checkToken($rule, $data);
    5. }
  • 说明:

  1. 规则可与是 token:表单令牌名称

    2.34 验证是否是合格的域名或IP activeUrl() 方法

  • 参数:

mixed $value 字段的值
string $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function activeUrl(string $value, string $rule = 'MX'): bool
    2. {
    3. if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) {
    4. $rule = 'MX';
    5. }
    6. return checkdnsrr($value, $rule);
    7. }
  • 说明:

  1. 规则可与是 activeUrl:A|MX...

    2.35 验证是否是有效IP ip() 方法

  • 参数:

mixed $value 字段的值
string $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function ip($value, string $rule = 'ipv4'): bool
    2. {
    3. if (!in_array($rule, ['ipv4', 'ipv6'])) {
    4. $rule = 'ipv4';
    5. }
    6. return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]);
    7. }
  • 说明:

  1. 规则可与是 ip:ipv4|ipv6

    2.36 检测上传文件后缀 checkExt() 方法

  • 参数:

\think\File $file 待检测的长传文件
string|array $ext 允许后缀 如:['jpeg', 'png']'jpeg,png'

  • 返回:bool
  • 源码:如下

    1. protected function checkExt(File $file, $ext): bool
    2. {
    3. if (is_string($ext)) {
    4. $ext = explode(',', $ext);
    5. }
    6. return in_array(strtolower($file->extension()), $ext);
    7. }

    2.37 检测上传文件大小 checkSize() 方法

  • 参数:

\think\File $file 待检测的上传文件
int $size 文件最大大小

  • 返回:bool
  • 源码:如下

    1. protected function checkSize(File $file, $size): bool
    2. {
    3. return $file->getSize() <= (int) $size;
    4. }

    2.38 检测上传文件MIME类型 checkMime() 方法

  • 参数:

\think\File $file 待检测的长传文件
string|array $mime 允许后缀 如:['image/jpeg', 'image/gif']'image/jpeg,image/gif'

  • 返回:bool
  • 源码:如下

    1. protected function checkMime(File $file, $mime): bool
    2. {
    3. if (is_string($mime)) {
    4. $mime = explode(',', $mime);
    5. }
    6. return in_array(strtolower($file->getMime()), $mime);
    7. }

    2.39 验证上传文件后缀 fileExt() 方法

  • 参数:

\think\File $file 待检测的长传文件
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function fileExt($file, $rule): bool
    2. {
    3. if (is_array($file)) {
    4. foreach ($file as $item) {
    5. if (!($item instanceof File) || !$this->checkExt($item, $rule)) {
    6. return false;
    7. }
    8. }
    9. return true;
    10. } elseif ($file instanceof File) {
    11. return $this->checkExt($file, $rule);
    12. }
    13. return false;
    14. }
  • 说明:

  1. 规则可与是 fileExt:jpeg,gif

    2.40 验证上传文件MIME类型 fileMime() 方法

  • 参数:

\think\File $file 待检测的长传文件
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function fileMime($file, $rule): bool
    2. {
    3. if (is_array($file)) {
    4. foreach ($file as $item) {
    5. if (!($item instanceof File) || !$this->checkMime($item, $rule)) {
    6. return false;
    7. }
    8. }
    9. return true;
    10. } elseif ($file instanceof File) {
    11. return $this->checkMime($file, $rule);
    12. }
    13. return false;
    14. }
  • 说明:

  1. 规则可与是 fileMime:image/jpeg,image/gif

    2.41 验证上传文件大小 fileSize() 方法

  • 参数:

\think\File $file 待检测的长传文件
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function fileSize($file, $rule): bool
    2. {
    3. if (is_array($file)) {
    4. foreach ($file as $item) {
    5. if (!($item instanceof File) || !$this->checkSize($item, $rule)) {
    6. return false;
    7. }
    8. }
    9. return true;
    10. } elseif ($file instanceof File) {
    11. return $this->checkSize($file, $rule);
    12. }
    13. return false;
    14. }
  • 说明:

  1. 规则可与是 fileSize:3000

    2.42 验证图片的宽高及类型 image() 方法

  • 参数:

\think\File $file 待检测的长传文件
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function image($file, $rule): bool
    2. {
    3. if (!($file instanceof File)) {
    4. return false;
    5. }
    6. if ($rule) {
    7. $rule = explode(',', $rule);
    8. [$width, $height, $type] = getimagesize($file->getRealPath());
    9. if (isset($rule[2])) {
    10. $imageType = strtolower($rule[2]);
    11. if ('jpg' == $imageType) {
    12. $imageType = 'jpeg';
    13. }
    14. if (image_type_to_extension($type, false) != $imageType) {
    15. return false;
    16. }
    17. }
    18. [$w, $h] = $rule;
    19. return $w == $width && $h == $height;
    20. }
    21. return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]);
    22. }
  • 说明:

  1. 规则可与是 image:300,600,jpg

    2.43 验证日期和时间是否符合指定格式dateFormat()方法

  • 参数:

mixed $vlaue 待验证数据
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function dateFormat($value, $rule): bool
    2. {
    3. $info = date_parse_from_format($rule, $value);
    4. return 0 == $info['warning_count'] && 0 == $info['error_count'];
    5. }
  • 说明:

  1. 规则可与是 dateFormat:y-m-d
  2. date_parse_from_format()说明见php官网。

    2.44 验证是否唯一 unique() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据
string $field 字段名

  • 返回:bool
  • 源码:如下 ```php public function unique($value, $rule, array $data = [], string $field = ‘’): bool { if (is_string($rule)) {

    1. $rule = explode(',', $rule);

    }

    if (false !== strpos($rule[0], ‘\‘)) {

    1. // 指定模型类
    2. $db = new $rule[0];

    } else {

    1. $db = $this->db->name($rule[0]);

    }

    $key = $rule[1] ?? $field; $map = [];

    if (strpos($key, ‘^’)) {

    1. // 支持多个字段验证
    2. $fields = explode('^', $key);
    3. foreach ($fields as $key) {
    4. if (isset($data[$key])) {
    5. $map[] = [$key, '=', $data[$key]];
    6. }
    7. }

    } elseif (isset($data[$field])) {

    1. $map[] = [$key, '=', $data[$field]];

    } else {

    1. $map = [];

    }

    $pk = !empty($rule[3]) ? $rule[3] : $db->getPk();

    if (is_string($pk)) {

    1. if (isset($rule[2])) {
    2. $map[] = [$pk, '<>', $rule[2]];
    3. } elseif (isset($data[$pk])) {
    4. $map[] = [$pk, '<>', $data[$pk]];
    5. }

    }

    if ($db->where($map)->field($pk)->find()) {

    1. return false;

    }

    return true; }

  1. - **说明**
  2. 1. 规则可以是`unique:table,field,except,pk`
  3. - **用法示例**
  4. ```php
  5. // 表示验证name在name字段的值是否在user表(不包含前缀)中唯一
  6. 'name' => 'unique:user',
  7. // 表示用User模型验证name在account字段中唯一
  8. 'name' => 'unique:\\User,account'
  9. // 验证其他字段
  10. 'name' => 'unique:user,account',
  11. // 排除某个主键值
  12. 'name' => 'unique:user,account,10',
  13. // 指定某个主键值排除
  14. 'name' => 'unique:user,account,10,user_id',
  15. // 多个字段验证唯一验证条件
  16. 'name' => 'unique:user,status^account',
  17. // 复杂验证条件
  18. 'name' => 'unique:user,status=1&account='.$data['account'],

2.45 使用filter_var方式验证 filter() 方法

  • 参数:

mixed $value 字段的值
string $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function filter($value, $rule): bool
    2. {
    3. if (is_string($rule) && strpos($rule, ',')) {
    4. [$rule, $param] = explode(',', $rule);
    5. } elseif (is_array($rule)) {
    6. $param = $rule[1] ?? null;
    7. $rule = $rule[0];
    8. } else {
    9. $param = null;
    10. }
    11. return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param);
    12. }

  • filter_var()参看php手册

    2.46 验证某个字段等于某个值的时候必须 requireIf() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function requireIf($value, $rule, array $data = []): bool
    2. {
    3. [$field, $val] = explode(',', $rule);
    4. if ($this->getDataValue($data, $field) == $val) {
    5. return !empty($value) || '0' == $value;
    6. }
    7. return true;
    8. }
  • 说明

  1. 规则可以是requireIf:field,value

    2.47 通过回调方法验证某个字段是否必须 requireCallback() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function requireCallback($value, $rule, array $data = []): bool
    2. {
    3. $result = call_user_func_array([$this, $rule], [$value, $data]);
    4. if ($result) {
    5. return !empty($value) || '0' == $value;
    6. }
    7. return true;
    8. }
  • 说明

  1. 规则可以是requireCallback:callable

    2.48 验证某个字段有值的情况下必须 requireWith() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function requireWith($value, $rule, array $data = []): bool
    2. {
    3. $val = $this->getDataValue($data, $rule);
    4. if (!empty($val)) {
    5. return !empty($value) || '0' == $value;
    6. }
    7. return true;
    8. }
  • 说明

  1. 规则可以是requireWith:field

    2.59 验证某个字段在没有值得情况下必须 requireWithout() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function requireWithout($value, $rule, array $data = []): bool
    2. {
    3. $val = $this->getDataValue($data, $rule);
    4. if (empty($val)) {
    5. return !empty($value) || '0' == $value;
    6. }
    7. return true;
    8. }
  • 说明

  1. 规则可以是requireWithout:field

    2.60 验证是否在范围内 in() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function in($value, $rule): bool
    2. {
    3. return in_array($value, is_array($rule) ? $rule : explode(',', $rule));
    4. }
  • 说明

  1. 规则可以是in:1,2,3

    2.61 验证是否不再某个范围内 notin() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function notIn($value, $rule): bool
    2. {
    3. return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));
    4. }
  • 说明

  1. 规则可以是notIn:1,2,3

    2.62 验证数据 between() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function between($value, $rule): bool
    2. {
    3. if (is_string($rule)) {
    4. $rule = explode(',', $rule);
    5. }
    6. [$min, $max] = $rule;
    7. return $value >= $min && $value <= $max;
    8. }
  • 说明

  1. 规则可以是between:1,10

    2.63 验证数据 notbetween() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function notBetween($value, $rule): bool
    2. {
    3. if (is_string($rule)) {
    4. $rule = explode(',', $rule);
    5. }
    6. [$min, $max] = $rule;
    7. return $value < $min || $value > $max;
    8. }
  • 说明

  1. 规则可以是notBetween:1,10

    2.64 验证数据长度 length() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function length($value, $rule): bool
    2. {
    3. if (is_array($value)) {
    4. $length = count($value);
    5. } elseif ($value instanceof File) {
    6. $length = $value->getSize();
    7. } else {
    8. $length = mb_strlen((string) $value);
    9. }
    10. if (is_string($rule) && strpos($rule, ',')) {
    11. // 长度区间
    12. [$min, $max] = explode(',', $rule);
    13. return $length >= $min && $length <= $max;
    14. }
    15. // 指定长度
    16. return $length == $rule;
    17. }
  • 说明

  1. 规则可以是length:1,10 length:10
  2. 验证数据是数组,验证的是数组项个数;数据是文件,验证的时文件长度;数据是字符串,验证的是字符串长度。

    2.65 验证数据最大长度 maxLength() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function max($value, $rule): bool
    2. {
    3. if (is_array($value)) {
    4. $length = count($value);
    5. } elseif ($value instanceof File) {
    6. $length = $value->getSize();
    7. } else {
    8. $length = mb_strlen((string) $value);
    9. }
    10. return $length <= $rule;
    11. }
  • 说明

  1. 规则可以是max:10
  2. 验证数据是数组,验证的是数组项个数;数据是文件,验证的时文件长度;数据是字符串,验证的是字符串长度。

    2.66 验证数据最小长度 min() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function min($value, $rule): bool
    2. {
    3. if (is_array($value)) {
    4. $length = count($value);
    5. } elseif ($value instanceof File) {
    6. $length = $value->getSize();
    7. } else {
    8. $length = mb_strlen((string) $value);
    9. }
    10. return $length >= $rule;
    11. }
  • 说明

  1. 规则可以是min:10
  2. 验证数据是数组,验证的是数组项个数;数据是文件,验证的时文件长度;数据是字符串,验证的是字符串长度。

    2.67 验证日期 after() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function after($value, $rule, array $data = []): bool
    2. {
    3. return strtotime($value) >= strtotime($rule);
    4. }
  • 说明

  1. 规则可以是after:2020-3-18

    2.68 验证日期 before() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function before($value, $rule, array $data = []): bool
    2. {
    3. return strtotime($value) <= strtotime($rule);
    4. }
  • 说明

  1. 规则可以是before:2020-3-18

    2.69 验证日期 afterWith() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function afterWith($value, $rule, array $data = []): bool
    2. {
    3. $rule = $this->getDataValue($data, $rule);
    4. return !is_null($rule) && strtotime($value) >= strtotime($rule);
    5. }
  • 说明

  1. 规则可以是afterWith:field

    2.70 验证容器 beforeWith() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则
array $data 验证数据

  • 返回:bool
  • 源码:如下

    1. public function beforeWith($value, $rule, array $data = []): bool
    2. {
    3. $rule = $this->getDataValue($data, $rule);
    4. return !is_null($rule) && strtotime($value) <= strtotime($rule);
    5. }
  • 说明

  1. 规则可以是beforeWith:field

    2.71 验证有效期 expire() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function expire($value, $rule): bool
    2. {
    3. if (is_string($rule)) {
    4. $rule = explode(',', $rule);
    5. }
    6. [$start, $end] = $rule;
    7. if (!is_numeric($start)) {
    8. $start = strtotime($start);
    9. }
    10. if (!is_numeric($end)) {
    11. $end = strtotime($end);
    12. }
    13. return time() >= $start && time() <= $end;
    14. }
  • 说明

  1. 规则可以是expire:2016-2-1,2016-10-01

    2.72 验证IP许可 allowIp() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function allowIp($value, $rule): bool
    2. {
    3. return in_array($value, is_array($rule) ? $rule : explode(',', $rule));
    4. }
  • 说明

  1. 规则可以是allowIp:allow1,allow2,...

    2.73 验证IP禁用 denyIp() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function denyIp($value, $rule): bool
    2. {
    3. return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));
    4. }
  • 说明

  1. 规则可以是denyIp:allow1,allow2,...

    2.74 使用正则验证数据 regex() 方法

  • 参数:

mixed $value 字段的值
mixed $rule 验证规则

  • 返回:bool
  • 源码:如下

    1. public function regex($value, $rule): bool
    2. {
    3. if (isset($this->regex[$rule])) {
    4. $rule = $this->regex[$rule];
    5. } elseif (isset($this->defaultRegex[$rule])) {
    6. $rule = $this->defaultRegex[$rule];
    7. }
    8. if (is_string($rule) && 0 !== strpos($rule, '/') && !preg_match('/\/[imsU]{0,4}$/', $rule)) {
    9. // 不是正则表达式则两端补上/
    10. $rule = '/^' . $rule . '$/';
    11. }
    12. return is_scalar($value) && 1 === preg_match($rule, (string) $value);
    13. }
  • 说明

  1. 规则可以是regex:\d{6} 或者直接 \d{6}
  2. 正则表到式中含有|符号时,必须用数组方式定义;
  3. 可以在验证器类中定义regex属性,正则表达式可以直接调用;
  4. 默认的正则表达式有alpha alphaNum alphaDash chs chsAlpha chsAlphaNum chsDash mobile idCard zip

    2.75 获取错误信息 getError() 方法

  • 参数:
  • 返回:mixed
  • 源码:如下

    1. public function getError()
    2. {
    3. return $this->error;
    4. }

    2.76 获取验证规则的错误提示信息 getRuleMsg() 方法

  • 参数:

string $attribute 字段英文名
string $title 字段描述名
string $type 验证规则名称

mixed $rule 验证规则

  • 返回:string|array
  • 源码:如下

    1. protected function getRuleMsg(string $attribute, string $title, string $type, $rule)
    2. {
    3. if (isset($this->message[$attribute . '.' . $type])) {
    4. $msg = $this->message[$attribute . '.' . $type];
    5. } elseif (isset($this->message[$attribute][$type])) {
    6. $msg = $this->message[$attribute][$type];
    7. } elseif (isset($this->message[$attribute])) {
    8. $msg = $this->message[$attribute];
    9. } elseif (isset($this->typeMsg[$type])) {
    10. $msg = $this->typeMsg[$type];
    11. } elseif (0 === strpos($type, 'require')) {
    12. $msg = $this->typeMsg['require'];
    13. } else {
    14. $msg = $title . $this->lang->get('not conform to the rules');
    15. }
    16. if (is_array($msg)) {
    17. return $this->errorMsgIsArray($msg, $rule, $title);
    18. }
    19. return $this->parseErrorMsg($msg, $rule, $title);
    20. }
  • 说明:

  1. message的优先级顺序

    2.77 获取验证规则的错误提示信息 parseErrorMsg() 方法

  • 参数:

string $msg 错误信息

mixed $rule 验证规则
string $title 字段描述

  • 返回:string
  • 源码:如下

    1. protected function parseErrorMsg(string $msg, $rule, string $title)
    2. {
    3. if (0 === strpos($msg, '{%')) {
    4. $msg = $this->lang->get(substr($msg, 2, -1));
    5. } elseif ($this->lang->has($msg)) {
    6. $msg = $this->lang->get($msg);
    7. }
    8. if (is_array($msg)) {
    9. return $this->errorMsgIsArray($msg, $rule, $title);
    10. }
    11. if (is_scalar($rule) && false !== strpos($msg, ':')) {
    12. // 变量替换
    13. if (is_string($rule) && strpos($rule, ',')) {
    14. $array = array_pad(explode(',', $rule), 3, '');
    15. } else {
    16. $array = array_pad([], 3, '');
    17. }
    18. $msg = str_replace(
    19. [':attribute', ':1', ':2', ':3'],
    20. [$title, $array[0], $array[1], $array[2]],
    21. $msg
    22. );
    23. if (strpos($msg, ':rule')) {
    24. $msg = str_replace(':rule', (string) $rule, $msg);
    25. }
    26. }
    27. return $msg;
    28. }

    2.78 错误信息数组处理 errorMsgIsArray() 方法

  • 参数:

string $msg 错误信息
mixed $rule 验证规则
string $title 字段描述

  • 返回:array
  • 源码:如下

    1. protected function errorMsgIsArray(array $msg, $rule, string $title)
    2. {
    3. foreach ($msg as $key => $val) {
    4. if (is_string($val)) {
    5. $msg[$key] = $this->parseErrorMsg($val, $rule, $title);
    6. }
    7. }
    8. return $msg;
    9. }

    2.79 动态方法 __call()

    1. public function __call($method, $args)
    2. {
    3. if ('is' == strtolower(substr($method, 0, 2))) {
    4. $method = substr($method, 2);
    5. }
    6. array_push($args, lcfirst($method));
    7. return call_user_func_array([$this, 'is'], $args);
    8. }

    3. 助手函数

    3.1 生成验证对象 validate() 函数

  • 参数:

string|array $validate 验证器类名|验证规则数组
array $message 错误提示信息
bool $batch 是否批量验证
bool $failException 是否抛出异常

  • 返回:Validate
  • 源码:如下

    1. function validate($validate = '', array $message = [], bool $batch = false, bool $failException = true): Validate
    2. {
    3. if (is_array($validate) || '' === $validate) {
    4. $v = new Validate();
    5. if (is_array($validate)) {
    6. $v->rule($validate);
    7. }
    8. } else {
    9. if (strpos($validate, '.')) {
    10. // 支持场景
    11. [$validate, $scene] = explode('.', $validate);
    12. }
    13. $class = false !== strpos($validate, '\\') ? $validate : app()->parseClass('validate', $validate);
    14. $v = new $class();
    15. if (!empty($scene)) {
    16. $v->scene($scene);
    17. }
    18. }
    19. return $v->message($message)->batch($batch)->failException($failException);
    20. }