CodeIgniter中如何防止level列值为Juri时重复插入
现有代码问题定位
你写的代码存在3个核心问题,完全无法实现需求:
- 校验触发逻辑完全写反:当前代码只要检测到库里已经存在level为Juri的记录,就给level字段加全局唯一校验,根本没判断本次提交的level是什么值。会导致只要库里有1条Juri数据,后续不管你提交什么角色(哪怕是普通参与者、管理员),都会被判定为重复,直接拦截。
- 校验规则用错:
is_unique[pengguna.level]的作用是强制整张表的level字段所有值都不能重复,和你要的「只有Juri不能重复,其他值可以随便重复」的需求完全冲突,会导致非Juri的角色只要之前存过,就再也插不进新数据。 - 语法错误:
$this->db->where('level' => 'Juri')是不符合PHP语法的,=>符号只能在定义数组的时候用,这里要么写成两个参数$this->db->where('level', 'Juri'),要么传数组$this->db->where(['level' => 'Juri']),原代码直接运行会报语法错误。
正确实现代码
调整核心逻辑:只在本次提交的level值为Juri时,才校验是否重复,其余情况直接放行,代码如下(基于CodeIgniter 3框架):
public function tambah() { // 保留原有的用户名唯一校验 $this->form_validation->set_rules( 'username', 'Username', 'is_unique[pengguna.username]', ['is_unique' => '%s sudah ada'] ); // 给level加基础必填校验,可根据自己的需求调整规则 $this->form_validation->set_rules( 'level', 'Level', 'required', ['required' => '%s tidak boleh kosong'] ); // 获取本次提交的level值 $submit_level = $this->input->post('level'); // 仅当提交的是Juri时,才做重复校验 if ($submit_level === 'Juri') { // 修正原where语法错误,查询已存在的Juri数量 $juri_count = $this->db->where('level', 'Juri') ->count_all_results('pengguna'); // 已经存在Juri记录,触发校验错误 if ($juri_count > 0) { $this->form_validation->set_rules( 'level', 'Level', 'callback_juri_duplicate_check', ['juri_duplicate_check' => 'Level Juri sudah ada, tidak boleh menambahkan data duplikat'] ); } } if ($this->form_validation->run() === FALSE) { $this->load->view('pengguna/tambah'); } else { $this->pengguna_model->insert(); $this->session->set_flashdata('sukses', '<div class="alert bg-success" role="alert">Data berhasil disimpan</div>'); redirect('pengguna'); } } // 自定义校验回调,固定返回false触发重复提示 public function juri_duplicate_check($value) { return false; }
逻辑说明:
- 不会在每次提交时都无意义查询Juri是否存在,仅当提交值确实是Juri时才查库,性能更好
- 非Juri的level值完全不做重复校验,不管库里存了多少条同值记录,都可以正常插入
- 从根源避免了全局is_unique规则导致的非Juri值无法重复插入的问题
- 修正了原代码的数据库查询语法错误,用
count_all_results替代get()->num_rows(),减少内存占用
内容的提问来源于stack exchange,提问作者Wenn
相关产品推荐
相关产品推荐

