Skip to content

Commit 159aa63

Browse files
authored
Merge pull request #24 from consatan/fix/each_required_other_way
fix#21 each required not work other way
2 parents 827d91a + 1a4586e commit 159aa63

File tree

5 files changed

+72
-39
lines changed

5 files changed

+72
-39
lines changed

README.md

+47-36
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ validate 同时支持两种规则配置方式,对应了两种规则的收集
4545
```php
4646
[
4747
['field', 'required|string:5,10|...', ...],
48-
// ... ...
48+
// ... ...
4949
]
5050
```
5151

@@ -115,45 +115,45 @@ class PageRequest extends Validation
115115
return [
116116
// 字段必须存在且不能为空
117117
['tagId,title,userId,freeTime', 'required'],
118-
118+
119119
// 4<= tagId <=567
120-
['tagId', 'size', 'min'=>4, 'max'=>567, 'filter' => 'int'],
121-
120+
['tagId', 'size', 'min'=>4, 'max'=>567, 'filter' => 'int'],
121+
122122
           // title length >= 40. 注意只需一个参数的验证,无需加 key, 如这里的 40
123123
           ['title', 'min', 40, 'filter' => 'trim'],
124-
124+
125125
           // 大于 0
126126
           ['freeTime', 'number'],
127-
127+
128128
// 含有前置条件
129129
['tagId', 'number', 'when' => function($data) {
130130
return isset($data['status']) && $data['status'] > 2;
131131
}],
132-
132+
133133
// 在验证前会先过滤转换为 int。并且仅会在指明场景名为 'scene1' 时规则有效
134134
           ['userId', 'number', 'on' => 'scene1', 'filter' => 'int'],
135135
['username', 'string', 'on' => 'scene2', 'filter' => 'trim'],
136-
136+
137137
// 使用自定义正则表达式
138138
['username', 'regexp' ,'/^[a-z]\w{2,12}$/'],
139-
139+
140140
// 自定义验证器,并指定当前规则的消息
141-
['title', 'custom', 'msg' => '{attr} error msg!' ],
142-
141+
['title', 'custom', 'msg' => '{attr} error msg!' ],
142+
143143
// 直接使用闭包验证
144-
['status', function($status) {
144+
['status', function($status) {
145145
if (is_int($status) && $status > 3) {
146146
return true;
147147
}
148148
return false;
149149
}],
150-
150+
151151
           // 标记字段是安全可靠的 无需验证
152152
           ['createdAt, updatedAt', 'safe'],
153153
];
154154
}
155-
156-
// 定义不同场景需要验证的字段。
155+
156+
// 定义不同场景需要验证的字段。
157157
// 功能跟规则里的 'on' 类似,两者尽量不要同时使用,以免混淆。
158158
public function scenarios(): array
159159
{
@@ -180,7 +180,7 @@ class PageRequest extends Validation
180180
'title.required' => 'O, 标题是必填项。are you known?',
181181
];
182182
}
183-
183+
184184
// 添加一个验证器。必须返回一个布尔值标明验证失败或成功
185185
protected function customValidator($title): bool
186186
{
@@ -270,7 +270,7 @@ class UserModel extends DataModel
270270
}
271271

272272
// on controller action ...
273-
class UserController
273+
class UserController
274274
{
275275
// in action
276276
// @api /user/add
@@ -319,7 +319,7 @@ $v = Validation::make($_POST,[
319319
if ($status > 3) {
320320
return true;
321321
}
322-
322+
323323
return false;
324324
}]
325325
```
@@ -328,7 +328,7 @@ $v = Validation::make($_POST,[
328328

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

331-
**注意:**
331+
**注意:**
332332

333333
- 每条规则的第一个元素**必须**_要验证的字段_(可以同时配置多个,可以是数组. type:`string|array`)
334334
- 第二个元素**必须****一个**验证器(字符串,闭包,可回调的对象或数组. type:`string|Closure|callable`)
@@ -339,15 +339,15 @@ $v = Validation::make($_POST,[
339339
// a full rule
340340
[
341341
// basic validate setting
342-
'field0,field1,...', 'validator', 'arg0', 'arg1', ...,
342+
'field0,field1,...', 'validator', 'arg0', 'arg1', ...,
343343

344344
// some extended option settings
345-
'skipOnEmpty' => 'bool',
346-
'msg' => 'string|array',
347-
'default' => 'mixed',
348-
'on' => 'string|array'
349-
'isEmpty' => 'callback(string|closure)',
350-
'when' => 'callback(string|closure)',
345+
'skipOnEmpty' => 'bool',
346+
'msg' => 'string|array',
347+
'default' => 'mixed',
348+
'on' => 'string|array'
349+
'isEmpty' => 'callback(string|closure)',
350+
'when' => 'callback(string|closure)',
351351
'filter' => 'callback(string|array|closure)'
352352
]
353353
```
@@ -444,7 +444,7 @@ $v = Validation::make($_POST,[
444444
提交的数据中 没有 `name` 字段或者 `$data['name']` 等于空都不会进行 `string` 验证;
445445
只有当 `$data['name']` **有值且不为空** 时才会验证是否是 `string`
446446

447-
如果要想为空时也检查, 请将此字段同时加入 `required` 规则中.
447+
如果要想为空时也检查, 请将此字段同时加入 `required` 规则中.
448448

449449
```php
450450
['name', 'required' ]
@@ -471,6 +471,17 @@ $v = Validation::make($_POST,[
471471
}]
472472
```
473473

474+
自定义 isEmpty 验证时,应留意 $value 是否为 ArrayValueNotExists 实例
475+
476+
```php
477+
['users.*.id', 'each', 'required', 'isEmpty' => function($value) {
478+
if ($value instanceof \Inhere\Validate\ArrayValueNotExists) {
479+
return true;
480+
}
481+
// your code here ...
482+
}]
483+
```
484+
474485
### `filter` -- 使用过滤器
475486

476487
支持在进行验证前对值使用过滤器进行净化过滤[内置过滤器](#built-in-filters)
@@ -641,7 +652,7 @@ $v = Validation::make($_POST,[
641652

642653
```php
643654
$v = Validation::make($_POST, [
644-
// [...],
655+
// [...],
645656
// some rules ...
646657
])
647658
->setUploadedFiles($_FILES)
@@ -653,9 +664,9 @@ $v = Validation::make($_POST, [
653664

654665
- **请将 `required*` 系列规则写在规则列表的最前面**
655666
- 规则上都支持添加过滤器
656-
- 验证大小范围 `int` 是比较大小。 `string``array` 是检查长度。大小范围 是包含边界值的
667+
- 验证大小范围 `int` 是比较大小。 `string``array` 是检查长度。大小范围 是包含边界值的
657668
- `size/range` `length` 可以只定义 `min` 或者 `max`
658-
- 支持对数组的子级值验证
669+
- 支持对数组的子级值验证
659670

660671
```php
661672
[
@@ -672,7 +683,7 @@ $v = Validation::make($_POST, [
672683
['goods.pear', 'max', 30], //goods 下的 pear 值最大不能超过 30
673684
```
674685

675-
- 支持对数组的子级值进行遍历验证
686+
- 支持对数组的子级值进行遍历验证
676687

677688
```php
678689
[
@@ -691,7 +702,7 @@ $v = Validation::make($_POST, [
691702
['goods.*', 'each', 'number'], //goods 下的 每个值 都必须为大于0 的整数
692703
// 写法是等效的
693704
// ['goods', 'each', 'number'], //goods 下的 每个值 都必须为大于0 的整数
694-
705+
695706
// 多维数组
696707
['users.*.id', 'each', 'required'],
697708
['users.*.id', 'each', 'number', 'min' => 34],
@@ -756,7 +767,7 @@ public function getErrors(): array
756767

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

759-
```php
770+
```php
760771
[
761772
['name' => 'field1', 'msg' => 'error Message1' ],
762773
['name' => 'field2', 'msg' => 'error Message2' ],
@@ -788,7 +799,7 @@ public function lastError($onlyMsg = true)
788799
public function getSafeData(): array|\stdClass
789800
```
790801

791-
获取所有 **验证通过** 的安全数据.
802+
获取所有 **验证通过** 的安全数据.
792803

793804
- 此数据数组只包含加入了规则验证的字段数据,不会含有额外的字段。(可直接省去后续的字段收集)
794805
- 推荐使用此数据进行后续操作,比如存入数据库等。
@@ -800,7 +811,7 @@ public function getSafeData(): array|\stdClass
800811
```php
801812
public function val(string $key, $default = null) // getSafe() 的别名方法
802813
public function getValid(string $key, $default = null) // getSafe() 的别名方法
803-
public function getSafe(string $key, $default = null)
814+
public function getSafe(string $key, $default = null)
804815
```
805816

806817
**验证通过** 的数据中取出对应 key 的值
@@ -823,7 +834,7 @@ public function getRaw(string $key, $default = null)
823834

824835
## 代码示例
825836

826-
可运行示例请看 `example`
837+
可运行示例请看 `example`
827838

828839
## 单元测试
829840

src/ArrayValueNotExists.php

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Inhere\Validate;
4+
5+
final class ArrayValueNotExists
6+
{
7+
}

src/ValidationTrait.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,8 @@ protected function getByWildcard(string $path, $default = null)
568568
$result = [];
569569

570570
foreach ($recently as $item) {
571-
if (is_array($item) && isset($item[$field])) {
572-
$result[] = $item[$field];
571+
if (is_array($item)) {
572+
$result[] = isset($item[$field]) ? $item[$field] : new ArrayValueNotExists();
573573
}
574574
}
575575
return $result;

src/Validators.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ public static function isEmpty($val): bool
116116
{
117117
if (is_string($val)) {
118118
$val = trim($val);
119-
119+
} elseif ($val instanceof ArrayValueNotExists) {
120+
$val = '';
120121
} elseif (is_object($val)) {
121122
$val = get_object_vars($val);
122123
}

test/RuleValidationTest.php

+14
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,20 @@ public function testEach(): void
547547
$this->assertFalse($v->isOk());
548548
$this->assertCount(1, $v->getErrors());
549549
$this->assertTrue($v->inError('users.*.name'));
550+
551+
$v = RuleValidation::check([
552+
'users' => [
553+
['id' => 34, 'name' => 'tom'],
554+
['name' => 'john'],
555+
],
556+
], [
557+
['users.*.id', 'each', 'required'],
558+
['users.*.id', 'each', 'number', 'min' => 34],
559+
]);
560+
561+
$this->assertFalse($v->isOk());
562+
$this->assertCount(1, $v->getErrors());
563+
$this->assertTrue($v->inError('users.*.id'));
550564
}
551565

552566
public function testMultiLevelData(): void

0 commit comments

Comments
 (0)