場景
- thinkphp的文檔向來是很簡陋, 所以當用出了一些問題的時候,需要看看源碼
- 公司的一個項目使用thinkphp5.0,今天驗證bug, 同事設置了場景 edit, create場景分別校驗,其中一個場景是校驗店名是否唯一, 同事採用了這樣的策略(爲了避免編輯模式, 店名唯一性校驗不通過的問題)
- 存在id,並且店名沒有更改的時候,不校驗店名的唯一性(即所謂的edit場景)
- 其實這樣搞邏輯也是可以自洽的,但是我們的業務場景還有一個可以文件批量導入的功能,那裏有些疏漏,導致了同名的店鋪出現了,所以在更新的時候,弔詭的事情出現了 : 店鋪的唯一性沒有校驗
解決
- thinkphp5.0 內置了更新和新建的唯一性的解決方案, 下面是源碼
- map[pk] = [‘neq’, 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;
}