codeigniter 中删除操作需严格校验请求方法、过滤id参数、使用预处理、支持软删除并记录日志:ci3须在控制器校验post、强转并过滤id;ci4禁用字符串拼接,须用query builder或prepare;物理删除前应加软删除开关和操作日志。

CodeIgniter 3 中 deleteAll() 方法必须校验请求方法
CI3 路由不支持 $route['itemDelete']['post'] 这类 HTTP 方法限定语法,强行使用会导致 404。路由只能做纯路径映射,安全校验必须下移到控制器里。
在 deleteAll() 开头加一层判断:
if (!$this->input->is_post()) { show_404(); }- 或更底层的
if ($_SERVER['REQUEST_METHOD'] !== 'POST') { show_404(); } - 避免通过 GET 直接访问触发删除,这是最基础但常被跳过的防线
传入 ID 列表必须过滤整形,禁止直接 explode + 未清洗使用
前端传来的 $ids = "1,2,3,abc,5" 如果直接 explode(',', $ids) 后进 SQL,会因类型混杂导致查询构建器报错,甚至绕过 WHERE 条件(取决于驱动行为)。
正确做法是逐个强转并丢弃非法值:
$id_array = array_map('intval', explode(',', $ids));$id_array = array_filter($id_array, function($v) { return $v > 0; });- 再用
$this->db->where_in('id', $id_array)->delete('table_name'); - 注意:CI3 的
where_in不会自动跳过 0 值,所以array_filter非常必要
CI4 中 Model 删除必须用预处理或 Query Builder,禁用字符串拼接
CI4 的 Model::delete() 默认支持主键数组,但若手动写 SQL(比如带 JOIN 的复杂删),必须走预处理流程。
错误示范:$this->db->query("DELETE FROM users WHERE id IN ($ids_str)");
正确路径有两条:
- 走 Query Builder:
$this->db->table('users')->whereIn('id', $id_list)->delete();(自动参数绑定) - 走原生预处理:
$builder = $this->db->prepare("DELETE FROM users WHERE id IN ?"); $builder->execute([$id_list]); - 切记:CI4 的
prepare()不接受多个占位符拼接,$id_list必须是数组,框架内部会处理展开
物理删除前建议加软删除开关和操作日志
真实业务中,误删比性能更重要。即使没做回收站,也应在删除前留一道可逆钩子。
- 检查配置项:
if (config('App')->softDelete === true) { $this->db->set('deleted_at', 'NOW()', false)->update('table_name', ['id' => $id]); return; } - 记录日志至少包含:
user_id、table_name、affected_rows、ip_address - 日志表本身建议用 MyISAM 或独立小库,避免大事务拖慢主业务
批量删的真实风险不在代码怎么写,而在“谁点的、为什么点、删完能不能追”。这两行日志和一个配置开关,比任何优化都管用。











