文章目录
- 场景
- thinkphp官方的解释
- 解决
- unqiue 源码
场景
- thinkphp的文档向来是很简陋, 所以当用出了一些问题的时候,需要看看源码
- 公司的一个项目使用thinkphp5.0,今天验证bug, 同事设置了场景 edit, create场景分别校验,其中一个场景是校验店名是否唯一, 同事采用了这样的策略(为了避免编辑模式, 店名唯一性校验不通过的问题)
- 存在id,并且店名没有更改的时候,不校验店名的唯一性(即所谓的edit场景)
- 其实这样搞逻辑也是可以自洽的,但是我们的业务场景还有一个可以文件批量导入的功能,那里有些疏漏,导致了同名的店铺出现了,所以在更新的时候,吊诡的事情出现了 : 店铺的唯一性没有校验
解决
- thinkphp5.0 内置了更新和新建的唯一性的解决方案, 下面是源码
- map[map[map[pk] = [‘neq’, data[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;}