gordensong/laravel-table-validator
简介
这是一个规则收集器。
- 复用规则
- 自定义规则
- 自动加载表规则
- 排除规则
- 场景规则
- 缓存规则
概念
Validator
:规则收集器。TableValidator
:表规则收集器(扩展表字段规则)。ValidatorCollection
:(表)规则收集器集合。scene
:规则场景。表规则收集器可以合并获取指定场景规则。规则收集器集合可以分别获取每个规则收集器的场景规则。
机制
- 规则合并优先级:
table rules
<$rules
|customizeRules()
<scene rules
,优先级高的规则覆盖优先级低的规则。 - 同一表字段规则:
required
优先级最高,排最前面,
使用
Validator
use GordenSong\Support\Validator;
class AuthorValidator extends Validator
{
protected $rules = [
'id' => ['integer'],
'name' => ['require','string'],
'age' => ['integer'],
'birth_date' => ['datetime'],
];
protected $scenes = [
'new' => ['name', 'age'],
'age' => ['id' => 'required', 'age' => 'required'],
'birth_date' => ['id' => 'required', 'birth_date' => 'required'],
];
}
1. scene()
scene()
规则覆盖$rules
规则。
public function scene(string ...$scenes) : static
用法 1.
$validator = new AuthorValidator();
print_r($validator->scene('new')->rules());
Array
(
[name] => Array
(
[0] => required
[1] => string
)
[age] => Array
(
[0] => integer
)
)
demo 用法 2:
print_r($validator->scene('age', 'birth_date')->rules());
Array
(
[id] => Array
(
[0] => required
[1] => integer
)
[age] => Array
(
[0] => required
[1] => integer
)
[birth_date] => Array
(
[0] => required
[1] => datetime
)
)
2. prefix( )
public function prefix(string $prefix, bool $required = false) : static
print_r($validator->prefix('author')->rules());
Array
(
[author] => Array
(
[0] => array // required = false
)
[author.id] => Array
(
[0] => integer
)
[author.name] => Array
(
[0] => required
[1] => string
)
...
)
print_r($validator->prefix('author', true)->rules());
Array
(
[author] => Array
(
[0] => required // required = true
[1] => array
)
[author.id] => Array
(
[0] => integer
)
[author.name] => Array
(
[0] => required
[1] => string
)
...
)
excludeRules()
排除字段一个或多个规则.
protected function excludeRules() : array {
return [
'key1' => ['string'], // 移除 key1 的 string 规则
'key2', // 移除整个 key2 规则
];
}
demo
namespace Tests\Validator;
use GordenSong\Support\Validator;
class ExcludeValidator extends Validator
{
// simulate table rules
protected $rules = [
'title' => ['string'],
'config' => ['string'],
'created_at' => ['datetime'],
'updated_at' => ['datetime'],
];
public function customizeRules(): array{
return [
'title' => ['string', 'required'],
'config' => ['array'],
];
}
public function excludeRules(): array{
return [
'config' => ['string'],
'created_at',
'updated_at',
];
}
}
$validator = new ExcludeValidator();
self::assertSame([
'title' => ['required', 'string'],
'config' => ['array']
], $validator->rules());
TableValidator
abstract class TableValidator extends Validator {
/** @var null|string */
protected $connection = null;
/** @var string */
protected $table;
public function tableRules(): array {}
}
author migration
Schema::create('author', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable(false);
$table->tinyInteger('age');
$table->enum('gender', [1, 2]);
});
AuthorTableValidator
class AuthorTableValidator extends TableValidator
{
protected $table = 'author';
protected $rules = [
'name' => ['min:2', 'max:20'],
'age' => ['max:150'],
'gender' => ['in:1,2']
];
}
tableRules()
public function tableRules(): array
self::assertSame([
'id' => ['integer', 'min:0',],
'name' => ['string', 'max:255',], // 注意 这里有 max 规则
'age' => ['integer', 'min:0', 'max:255',],
'gender' => ['string',],
], $this->authorValidator->tableRules());
rules()
$rules
覆盖tableRules()
的规则.
public function rules(): array
self::assertSame([
'id' => ['integer', 'min:0',],
'name' => ['string','max:20', 'min:2', ], // table rule 含有 max, 所以 max 在 min 前面
'age' => ['integer', 'min:0', 'max:150',],
'gender' => ['string', 'in:1,2'],
], $this->authorValidator->rules());
ValidatorCollection
$rules = ValidatorCollection::make(
(new AuthorValidator())->prefix('author'),
(new AddressValidator())->prefix('address')
)->rules();
dump($rules);
array:7 [
"author" => array:1 [
0 => "array"
]
"author.id" => array:1 [
0 => "integer"
]
"author.name" => array:2 [
0 => "required"
1 => "string"
]
"author.age" => array:1 [
0 => "integer"
]
"author.birth_date" => array:1 [
0 => "datetime"
]
"address" => array:1 [
0 => "array"
]
"address.city" => array:1 [
0 => "string"
]
]
Macro
Validator::macro('validate', function (array $data) {
/** @var Factory $factory */
$factory = app(Factory::class);
/** @var Validator $this */
return $factory->validate($data, $this->rules(), $this->messages(), $this->attributes());
});
$data = [
'name' => 'a',
'age' => 10,
];
$validated = (new AuthorValidator())->validate($data);
self::assertSame($data, $validated);
ValidatorCollection::macro('validate', function (array $data) {
/** @var Factory $factory */
$factory = app(Factory::class);
/** @var Validator $this */
return $factory->validate($data, $this->rules(), $this->messages(), $this->attributes());
});
$data = [
'name' => 'a',
'age' => 10,
];
$validated = ValidatorCollection::make(new AuthorValidator())->validate($data);
self::assertSame($data, $validated);
Command
vendor:publish
php artisan vendor:publish
# select Provider: GordenSong\Providers\LaravelTableValidatorServiceProvider
# publish table-validator.php to /config/
validator
validator
validator:cache {connection} Generate one or more table validator cache
validator:make {table*} {--connection=mysql} [options] <table>... Generate one or more table validators
生成 Validator
默认文件位置: app/Validators/BooksValidator.php
php artisan validator:make . # 为默认数据库所有的表自动生成 Validator
php artisan validator:make tablename # 为指定表生成 Validator
php artisan validator:make tablename --force # overwrite the file
php artisan validator:make tablename --force --connection=mysql
缓存表规则
根据 config/table-validator.php 设置规则缓存生成目录。
php artisan validator:cache {connection} {-d}
-d 删除缓存
# bootstrap/cache/table-validator/{$connection}/{$table}.php
php artisan validator:cache mysql