When we need to pass the validator validate
to uniquely check the fields in the database, we can use the unique
rule to achieve, but tp
is not very detailed description and examples.
At the same time unique
the validator needs to verify the uniqueness of the data outside 除当前活动记录
, it does not do the relevant encapsulation, and can only hard-write the rules at the business level, which is not elegant. The so-called validation rules should be in the validator.
Here are some scenes from my daily development to sort out for you:
unique
Syntax rules
// modelClassName 你需要关联校验的模型类名(直接写表名会比较硬编码)
// col1^col2 参与唯一校验的字段
// [
// ['col1', '=', $formData['col1']],
// ['col2', '=', $formData['col2']],
// ]
// $pkId 「编辑」场景防自杀
// [['id', '<>', $pkId]]
protectd $rule = [
"colName" => "require|unique:modelClassName,col1[^col2][,$pkId]"
]
// 给出具体规则所组装出的唯一性查询语句
// "require|unique:User,name^deleted"
$exists = $query->where([
'name' => $formData['name'],
'deleted' => $formData['deleted']
])->find();
// "require|unique:User,name^deleted, 1"
$exists = $query->where([
'name' => $formData['name'],
'deleted' => $formData['deleted']
])->where([['id', '<>', 1]])->find();
模型
/**
* @property int $id
* @property string $name 唯一
* @property int $age
* @property int $deleted 软删除
class User extends Model
{
protected $connection = "db_app";//多库链接配置
}
验证器基类-优化ed
According to whether there is ---0a731fafea3a2d30437baa3102525ecb 表单数据
in pkId
to dynamically generate the verification rules of unique
<?php
namespace app\common\validate;
use think\Validate;
/**
* Class MaterialTypeValidate
*
* @package app\prt\validate
* @see \think\Validate::unique 解析器
*/
class BaseValidate extends Validate
{
/**
* 根据表单数据动态挂载 pkId
* 编辑时的 unique 校验 应使用 pkId 来忽略当前行
* 同时如果有软删除 那么还要加入 deleted=0 的条件来限制只校验有效记录
* formData ['col1' => xxx, 'col2' => xxx, 'deleted'=>0]
* unique|modelName,col1^col2^deleted,pkId
* unique多字段校验时验证器会检查表单数据有对应的字段,存在才会加入条件
* 为了忽略软删除要让表单数据中的 deleted=0 显示定义,排除已删除的数据
* BaseValidate constructor.
*
* @param int $pkId
* @param array $rules
* @param array $message
* @param array $field
*/
public function __construct($pkId = 0, array $rules = [], array $message = [], array $field = [])
{
parent::__construct($rules, $message, $field);
// 有 id 则为编辑,追加pkId条件
// 无 id 则为新增,全局唯一检查
array_walk($this->rule, function (&$row) use ($pkId) {
$row = str_replace(",{pkId}", "," . $pkId ?? "", $row);
}, $this->rule);
}
}
The field uniqueness of ---8a6a88ded801671aa610b1d864199d92 全局有效记录
needs to be verified when adding, and the field uniqueness of 编辑
needs to be verified when 除当前记录外
.
<?php
namespace app\http\validate;
use app\common\validate\BaseValidate;
use app\http\model\User;
/**
* Class UserValidate
*
* @package app\http\validate
*/
class UserValidate extends BaseValidate
{
protected $rule = [
'id' => 'require|number',
'name' => 'require|unique:' . User::class . ',name^deleted,{pkId}',
'age' => 'require|number',
];
protected $message = [
'id.require' => 'id无效',
'id.number' => 'id无效',
'name.require' => '姓名必须',
'name.unique' => '姓名重复',
'age.require' => '年龄必须',
'age.number' => '年龄无效',
];
protected $scene = [
'add' => ['name', 'age'],
'edit' => ['id', 'name', 'age'],
];
}
实例
public function save($userData)
{
// 根据有无 id 来动态渲染 unique 条件的校验范围
$validate = new UserValidate($userData['id'] ?? 0);
// 只校验未删除的有效数据
if (User::hasSoftDelete()) {
$userData['deleted'] = 0;
}
if (empty($userData['id'])) {
$validateRes = $validate->scene('add')->check($userData);
} else {
$validateRes = $validate->scene('edit')->check($userData);
}
if (!$validateRes) {
throw new Exception($validate->getError());
}
}
Parser for unique
\think\Validate::unique
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。