codeigniter 3 的 $this->db->delete() 直接生成 delete 语句,不自动加事务、不校验主键、不触发钩子;省略 where 会删全表;返回 true 仅表示执行成功且影响行数≥1,affected_rows() 为 0 时不报错但未删除数据。

CodeIgniter 3 的 $this->db->delete() 基本写法
直接调用 $this->db->delete() 是最常用的方式,它会生成并执行 DELETE FROM table WHERE ... 语句。注意:它**不会**自动加事务、不会校验主键、也不会触发模型钩子(除非你手动封装在模型里)。
常见写法:
$this->db->where('id', 123);
$this->db->delete('users');
等价于:DELETE FROM users WHERE id = 123。也可以链式调用:$this->db->delete('users', ['id' => 123]);
- 第二个参数是可选的
WHERE条件数组,适合简单等值条件 - 如果省略条件(即只写
$this->db->delete('users')),会删全表 —— 这在生产环境极其危险,CI 不做任何防护 - 返回布尔值:
true表示至少影响一行,false表示失败或未匹配到数据(注意:不是“没删成”,而是 SQL 执行失败或affected_rows === 0)
为什么 $this->db->delete() 有时不报错却没删掉数据
最常见原因是 WHERE 条件没匹配到任何记录,但 CI 默认把 affected_rows === 0 当作“执行成功但无影响”,不抛异常。开发者误以为删成功了,其实什么都没动。
- 检查
$this->db->affected_rows():删完立刻调用,非零才表示真删了 - 确认字段名和值类型是否一致:比如数据库里
status是 tinyint(1),但你传'active'字符串,条件失效 - 注意自动转义:CI 会对数组条件里的值自动转义,但如果你手拼
where()字符串(如$this->db->where("id = $id")),可能被注入或解析错 - 事务未提交:如果在事务中执行但忘了
$this->db->commit(),回滚后看起来像“没删”
CodeIgniter 4 的 $model->delete() 和 CI3 的区别
CI4 推荐用模型的 delete() 方法,它默认按主键删单条,语义更清晰,也支持软删除(如果启用 $useSoftDeletes = true)。
// CI4 模型中 $userModel = new \App\Models\UserModel(); $userModel->delete(123); // 按主键删
- 传整数:按主键删一条;传数组(如
[1,2,3]):批量删多条主键;传关联数组(如['status' => 'draft']):按条件删(此时不走主键逻辑) - 如果模型启用了软删除,
delete()默认只是更新deleted_at字段,不是真删 —— 这和 CI3 的$this->db->delete()行为完全不同 - 要强制物理删除,得显式调用
$model->forceDelete($id) - CI4 的查询构造器也有
$this->db->table('users')->delete(['id' => 123]),行为接近 CI3,但不推荐,破坏模型封装
删前必须做的三件事(线上环境)
别只盯着语法对不对,线上删数据的核心风险从来不在函数怎么写,而在上下文控制。
- 加权限校验:确保当前用户有删除该记录的权限,不能只靠前端隐藏按钮
- 加日志记录:删之前记下操作人、时间、ID、IP,哪怕只是写进文件或数据库审计表
- 加二次确认机制:对关键数据(如订单、用户、配置),不要用 JS 确认框应付,应跳转到独立确认页,带 token 防重放,并显示将被删除的数据摘要
CI 自身不提供这些,得你自己补。函数写得再标准,漏掉其中一环,出事就是不可逆的。











