CodeIgniter 的 update() 方法必须配合 where() 等条件方法使用,否则会更新整张表;CI3 依赖链式调用,CI4 模型支持 update($id, $data) 自动主键匹配,且务必校验 ID、检查影响行数、避免空格与未过滤输入。

CodeIgniter 的 update() 方法本身不接受 WHERE 条件作为参数,必须配合 where() 或 where_in() 等条件方法一起用,否则会更新整张表 —— 这是生产环境最常导致数据事故的原因。
update() 必须搭配 where() 才安全
CodeIgniter 的 Query Builder 不允许把 WHERE 条件直接塞进 update() 调用里。它只接收两个参数:update($table, $data),其中 $table 是表名(可选,若已通过 from() 或模型指定则可省略),$data 是要更新的字段数组。WHERE 条件必须提前用 where() 设置。
- 错误写法(会更新全表或报错):
$this->db->update('users', $data, 'id = 123');—— 第三个参数被忽略 - 正确写法:
$this->db->where('id', 123)->update('users', $data); - 多条件也一样:
$this->db->where('status', 'pending')->where('type', 'invoice')->update('orders', $data); - 使用主键更新更稳妥:
$this->db->where('id', $id)->update('users', $data);,避免 WHERE 匹配多行
CI3 和 CI4 的 update() 行为差异
CI3 的 update() 是纯 Query Builder 方法,完全依赖链式调用;CI4 的 Model 类提供了更封装的 update($id, $data) 方法,内部自动把 $id 当作主键条件,更难出错。
- CI3 推荐写法:
$this->db->where('id', $id)->update('users', $data); - CI4 模型写法:
$this->userModel->update($id, $data);(前提是模型中$primaryKey = 'id'已定义) - CI4 若用 Query Builder:
$builder = $this->db->table('users'); $builder->where('id', $id)->update($data); - 注意:CI4 的
update($data)单参数形式不带条件,等同于全表更新,绝对禁用
容易踩的坑:空格、未校验、无返回检查
看似简单的更新,实际线上故障多源于低级疏忽。下面这些点不处理,轻则更新失败不报错,重则误改全表。
- 表名或字段名末尾有空格:
'users '→update()可能静默失败或作用于错误表 - 没校验
$id是否合法:if (!$id || !is_numeric($id)) { return false; }必须加 - 没检查影响行数:
if ($this->db->affected_rows() === 0) { log_message('error', 'No row updated for ID: '.$id); } - 没过滤输入:
$this->input->post('email', true)的第二个true启用 XSS 过滤,别省略
批量更新多个 ID 的正确姿势
想一次更新一批记录(比如状态批量设为「已发货」),别用循环调用 update(),性能差还易超时。用 where_in() + 单次 update()。
- 示例:
$ids = [101, 102, 105]; $this->db->where_in('id', $ids)->update('orders', ['status' => 'shipped']); - 注意:
$ids必须是整型数组,字符串 ID 需提前array_map('intval', $ids) - 如果 ID 数量极大(如上万),考虑分批执行,避免 SQL 语句过长或内存溢出
- CI4 模型不直接支持
where_in链式调用,需用$builder->whereIn('id', $ids)或手写原生 SQL
真正危险的不是不会写 update(),而是写了却没意识到 WHERE 条件是否生效、是否唯一、是否被截断。每次写完,用 $this->db->last_query() 看一眼生成的 SQL,比任何文档都管用。


















