gordensong / laravel-table-validator
簡介
這是一個基於 laravel 的規則收集器。將規則可以像積木一樣任意搭建。可以自定義呼叫方式。
- 複用規則
- 自定義規則
- 自動載入表規則
- 排除規則
- 場景規則
- 快取規則
概念
Validator
:規則收集器。TableValidator
:表規則收集器(擴充套件表欄位規則)。Collection
:(表)規則收集器集合。scene
:規則場景。表規則收集器可以合併獲取指定場景規則。規則收集器集合可以分別獲取每個規則收集器的場景規則。
機制
- 規則合併優先順序:
table rules
<$rules
|customizeRules()
<excludeRules()
<scene rules
,優先順序高的規則覆蓋優先順序低的規則。 - 同一表欄位規則:
required
優先順序最高,排最前面,
2. 基礎篇
2.1 migrations
user
Schema::create('user', function (Blueprint $table) {
$table->id();
$table->string('username', 50)->nullable(false);
$table->string('password', 50)->nullable(false);
$table->timestamps();
$table->softDeletes();
});
user_info
Schema::create('user_info', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->nullable(false)->default(0);
$table->string('xing')->nullable(true)->comment('姓');
$table->string('ming')->nullable(true)->comment('名');
$table->integer('age')->default(0);
$table->json('config1');
$table->text('config2')->comment('序列化欄位');
});
user_address
Schema::create('user_address', function (Blueprint $table) {
$table->id();
$table->integer('user_id')->nullable(false)->default(0);
$table->string('province')->default('')->comment('省');
$table->string('city')->default('')->comment('市');
$table->string('district')->default('')->comment('區');
$table->string('address', 255)->default('')->comment('詳細地址');
$table->timestamps();
$table->softDeletes();
});
2.2 命令建立 Table Validator
2.2.1 建立指定表的 Validator
php artisan validator:make user user_info --connection=mysql --force
輸出
Table validator created: /home/gorden/Workspace/laravel-model-validator-app/app/Validators/Mysql/UserValidator.php
2.2.2 建立所有表的 Validator
php artisan validator:make . --connection=mysql --force
輸出
Table validator created: /home/gorden/Workspace/laravel-model-validator-app/app/Validators/Mysql/UserValidator.php
Table validator created: /home/gorden/Workspace/laravel-model-validator-app/app/Validators/Mysql/UserAddressValidator.php
Table validator created: /home/gorden/Workspace/laravel-model-validator-app/app/Validators/Mysql/UserInfoValidator.php
以下是自動生成的 Validator
UserValidator
<?php
namespace App\Validators\Mysql;
class UserValidator extends \GordenSong\Support\TableValidator
{
protected $connection = 'mysql'; // 作者注: 預設 mysql 可以不設定
protected $table = 'user';
public function customizeRules(): array
{
return [
'id' => ['required'], // 作者注: 資料庫非空所以自動追加 'required' 規則
'username' => ['required'],
'password' => ['required'],
'created_at' => [],
'updated_at' => [],
'deleted_at' => [],
];
}
/**
* 作者注:驗證要排除的欄位
*/
public function excludeRules(): array
{
return [
'created_at',
'updated_at',
'deleted_at',
];
}
protected $messages = [
];
protected $attributes = [
];
protected $scenes = [
];
}
UserInfoValidator
<?php
namespace App\Validators\Mysql;
class UserInfoValidator extends \GordenSong\Support\TableValidator
{
protected $connection = 'mysql';
protected $table = 'user_info';
public function customizeRules(): array
{
return [
'id' => ['required'],
'user_id' => ['required'],
'xing' => [],
'ming' => [],
'age' => ['required'],
'config1' => ['required'],
'config2' => ['required'],
];
}
public function excludeRules(): array
{
return [
];
}
protected $messages = [
];
protected $attributes = [
];
protected $scenes = [
];
}
UserAddressValidator
<?php
namespace App\Validators\Mysql;
class UserAddressValidator extends \GordenSong\Support\TableValidator
{
protected $connection = 'mysql';
protected $table = 'user_address';
public function customizeRules(): array
{
return [
'id' => ['required'],
'user_id' => ['required'],
'province' => ['required'],
'city' => ['required'],
'district' => ['required'],
'address' => ['required'],
'created_at' => [],
'updated_at' => [],
'deleted_at' => [],
];
}
public function excludeRules(): array
{
return [
'created_at',
'updated_at',
'deleted_at',
];
}
protected $messages = [
];
protected $attributes = [
];
protected $scenes = [
];
}
2.2.3 方法介紹
2.2.3.1 rules()
獲取規則
右邊的規則覆蓋左邊的規則: tableRules, customizeRules, excludeRules, scene rules.
$rules = UserValidator::instance()->rules();
dump($rules);
array:3 [
"id" => array:3 [
0 => "required"
1 => "integer"
2 => "min:0"
]
"username" => array:3 [
0 => "required"
1 => "string"
2 => "max:50"
]
"password" => array:3 [
0 => "required"
1 => "string"
2 => "max:50"
]
]
2.2.3.2 customizeRules()
定製規則
如對 UserValidator 的規則不滿意,你可以
- 追加
- 覆蓋
public function customizeRules(): array
{
return [
// ...
'username' => ['required', 'max:30', 'min:3'],
//...
];
}
// 結果
array:3 [
"id" => ...
"username" => array:4 [
0 => "required"
1 => "string"
2 => "max:30"
3 => "min:3"
]
"password" => ...
]
2.2.3.3 excludeRules()
排除規則
你對結果還是不滿意,想去掉 username
的規則 min:3
。
public function excludeRules(): array
{
return [
// 排除整個驗證欄位
'created_at',
'updated_at',
'deleted_at',
// 排除指定欄位的部分規則
// 你可以寫多個規則, 你可以簡寫規則,只寫“:”前面的內容。
'username' => ['min'],
];
}
array:3 [
...,
"username" => array:3 [
0 => "required"
1 => "string"
2 => "max:30"
],
...
]
2.2.3.4 prefix($prefix, bool $required = false)
示例 1
$validator = UserValidator::instance()->prefix('user');
dump($validator->rules());
array:4 [
"user" => array:1 [
0 => "array"
]
"user.id" => array:3 [
0 => "required"
1 => "integer"
2 => "min:0"
]
"user.username" => array:3 [
0 => "required"
1 => "string"
2 => "max:30"
]
"user.password" => array:3 [
0 => "required"
1 => "string"
2 => "max:50"
]
]
示例2: 表單陣列
$validator = UserValidator::instance()->prefix('users.*', true);
dump($validator->rules());
array:5 [
"users" => array:2 [
0 => "required"
1 => "array"
]
"users.*" => array:2 [
0 => "required"
1 => "array"
]
"users.*.id" => array:3 [
0 => "required"
1 => "integer"
2 => "min:0"
]
"users.*.username" => array:3 [
0 => "required"
1 => "string"
2 => "max:30"
]
"users.*.password" => array:3 [
0 => "required"
1 => "string"
2 => "max:50"
]
]
2.2.3.5 addRule(string $key, array $rules)
追加規則
$validator = UserValidator::instance()->addRule('password_confirm', ['required']);
dump($validator->rules());
array:4 [
"id" => array:3 [
0 => "required"
1 => "integer"
2 => "min:0"
]
"username" => array:3 [
0 => "required"
1 => "string"
2 => "max:30"
]
"password" => array:3 [
0 => "required"
1 => "string"
2 => "max:50"
]
"password_confirm" => array:1 [
0 => "required"
]
]
2.2.3.6 exclude(array $rules)
排除規則
$validator = UserValidator::instance()->exclude(['id', 'password' => ['required']]);
dump($validator->rules());
array:2 [
"username" => array:3 [
0 => "required"
1 => "string"
2 => "max:30"
]
"password" => array:2 [
0 => "string"
1 => "max:50"
]
]
3 中級用法
3.1 scene(string ...$scene)
scene()
規則覆蓋$rules
規則。
<?php
namespace Tests\Validators\Mysql;
class UserInfoValidator extends \GordenSong\Support\TableValidator
{
protected $connection = 'mysql';
protected $table = 'user_info';
public function customizeRules(): array
{
return [
'id' => ['required'],
'user_id' => ['required'],
'xing' => [],
'ming' => [],
'age' => ['required'],
'config1' => ['required'],
'config2' => ['required'],
];
}
protected $scenes = [
'edit-name' => ['user_id' => 'required', 'xing' => 'required', 'ming' => 'required'],
'edit-age' => ['user_id' => 'required', 'age'],
];
}
示例 1
$validator = UserInfoValidator::instance()->scene('edit-name');
dump($validator->rules());
array:3 [
"user_id" => array:4 [
0 => "required"
1 => "integer"
2 => "min:-2147483648"
3 => "max:2147483647"
]
"xing" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
"ming" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
]
示例 2
$validator = UserInfoValidator::instance()->scene('edit-name', 'edit-age');
dump($validator->rules());
array:4 [
"user_id" => array:4 [
0 => "required"
1 => "integer"
2 => "min:-2147483648"
3 => "max:2147483647"
]
"xing" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
"ming" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
"age" => array:4 [
0 => "required"
1 => "integer"
2 => "min:-2147483648"
3 => "max:2147483647"
]
]
3.2 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);
Collection::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 = Collection::make(new AuthorValidator())->validate($data);
self::assertSame($data, $validated);
你也可以
$validator->validateRequest()
,你想怎麼用怎麼用!
4 高階用法
Validator, Collection 就像一個個積木,發揮你的想象力,使用它吧。
$collection = Collection::make([
Collection::make([
UserValidator::instance(),
EmailValidator::instance(),
QqValidator::instance()
])->prefix('user'),
UserInfoValidator::instance()->exclude(['id', 'user_id'])->prefix('user_info'),
UserAddressValidator::instance()->exclude(['id', 'user_id'])->prefix('user_address.*'),
]);
dump($collection->rules());
array:22 [
"user" => array:1 [
0 => "array"
]
"user.id" => array:3 [
0 => "required"
1 => "integer"
2 => "min:0"
]
"user.username" => array:3 [
0 => "required"
1 => "string"
2 => "max:30"
]
"user.password" => array:3 [
0 => "required"
1 => "string"
2 => "max:50"
]
"user.email" => array:2 [
0 => "string"
1 => "email"
]
"user.qq" => array:1 [
0 => "numeric"
]
"user_info" => array:1 [
0 => "array"
]
"user_info.xing" => array:2 [
0 => "string"
1 => "max:255"
]
"user_info.ming" => array:2 [
0 => "string"
1 => "max:255"
]
"user_info.age" => array:4 [
0 => "required"
1 => "integer"
2 => "min:-2147483648"
3 => "max:2147483647"
]
"user_info.config1" => array:2 [
0 => "required"
1 => "json"
]
"user_info.config2" => array:3 [
0 => "required"
1 => "string"
2 => "max:65535"
]
"user_address" => array:1 [
0 => "array"
]
"user_address.*" => array:1 [
0 => "array"
]
"user_address.*.province" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
"user_address.*.city" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
"user_address.*.district" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
"user_address.*.address" => array:3 [
0 => "required"
1 => "string"
2 => "max:255"
]
]
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
本作品採用《CC 協議》,轉載必須註明作者和本文連結