场景
- thinkphp的文档向来是很简陋, 所以当用出了一些问题的时候,需要看看源码
- 公司的一个项目使用thinkphp5.0,今天验证bug, 同事设置了场景 edit, create场景分别校验,其中一个场景是校验店名是否唯一, 同事采用了这样的策略(为了避免编辑模式, 店名唯一性校验不通过的问题)
- 存在id,并且店名没有更改的时候,不校验店名的唯一性(即所谓的edit场景)
- 其实这样搞逻辑也是可以自洽的,但是我们的业务场景还有一个可以文件批量导入的功能,那里有些疏漏,导致了同名的店铺出现了,所以在更新的时候,吊诡的事情出现了 : 店铺的唯一性没有校验
thinkphp官方的解释
解决
- thinkphp5.0 内置了更新和新建的唯一性的解决方案, 下面是源码
- m a p [ map[ map[pk] = [‘neq’, d a t a [ data[ data[pk]];
- 只要更新的时候带上id
unqiue 源码
protected function unique($value, $rule, $data, $field)
{
if (is_string($rule)) {
$rule = explode(',', $rule);
}
if (false !== strpos($rule[0], '\\')) {
$db = new $rule[0];
} else {
try {
$db = Loader::model($rule[0]);
} catch (ClassNotFoundException $e) {
$db = Db::name($rule[0]);
}
}
$key = isset($rule[1]) ? $rule[1] : $field;
if (strpos($key, '^')) {
$fields = explode('^', $key);
foreach ($fields as $key) {
$map[$key] = $data[$key];
}
} elseif (strpos($key, '=')) {
parse_str($key, $map);
} else {
$map[$key] = $data[$field];
}
$pk = isset($rule[3]) ? $rule[3] : $db->getPk();
if (is_string($pk)) {
if (isset($rule[2])) {
$map[$pk] = ['neq', $rule[2]];
} elseif (isset($data[$pk])) {
$map[$pk] = ['neq', $data[$pk]];
}
}
if ($db->where($map)->field($pk)->find()) {
return false;
}
return true;
}