当咱们须要通过验证器 validate
来对数据库中的字段做唯一性校验时,能够通过 unique
规定实现,但 tp
并没有很具体的阐明如何应用。
这里联合我日常开发中的一些场景,给大家整顿一下:
unique
语法规定
// modelClassName 你须要关联校验的模型类名(间接写表名会比拟硬编码)// col1^col2 参加惟一校验的字段
// [// ['col1', '=', $formData['col1']],
// ['col2', '=', $formData['col2']],
// ]
// $pkId「编辑」场景防他杀
// [['id', '<>', $pkId]]
protectd $rule = ["colName" => "require|unique:modelClassName,col1[^col2][,$pkId]"
]
模型
/**
* @property int $id
* @property string $name 惟一
* @property int $age
* @property int $deleted 软删除
class User extends Model
{protected $connection = "db_app";// 多库链接配置}
校验器基类
依据表单数据中是否有 pkId
来动静的调整 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);
}
}
新增时须要校验 全局无效记录
的字段唯一性,编辑
时须要校验 除以后记录外
的字段唯一性。
<?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());
}
}
unique
的解析器
\think\Validate::unique