codeigniter 默认自动转义防sql注入,但混用escape()与原生query易致双重转义;应优先使用query builder(如insert()),必要时仅用$db->escape()一次且不加引号,排查时查数据库实际存储而非输出。

CodeIgniter 默认会对插入数据库的数据进行转义处理,防止 SQL 注入,但有时会导致单引号、双引号、反斜杠等特殊字符被额外添加反斜杠(如 ' 变成 \'),尤其在使用 $this->db->query() 或手动拼接 SQL 时容易出现重复转义问题。
确认是否开启了自动转义
CodeIgniter 的 Query Builder(如 insert()、update())默认已做安全转义,无需手动调用 escape();若混用原生 SQL 和 escape(),就容易双重转义。检查是否在模型或控制器中误用了:
-
$this->db->escape($str)后又传给query("INSERT INTO...") - 开启了
mysqli_real_escape_string类似的自定义过滤,且与 CI 内置机制叠加 - 数据库配置中设置了
'escape' => TRUE(CI 4 中已弃用,CI 3 中极少手动设)
推荐做法:优先使用 Query Builder
让 CodeIgniter 自动处理转义,避免手动干预:
- 用
$this->db->insert('table', $data),其中$data是关联数组,值保持原始内容(如'O\'Reilly'不用预先加反斜杠) - 用
$this->db->set()+$this->db->insert()组合,同样由框架完成转义 - 如需动态字段,用
$this->db->escape_str($str)(仅用于字符串拼接场景,非完整 SQL)
必须写原生 SQL 时的处理原则
若无法避免 query(),请严格遵循一条:只让 CodeIgniter 转义一次。
- 不要对变量先用
addslashes()或mysql_real_escape_string() - 应使用
$this->db->escape()获取已转义字符串,再拼入 SQL:$name = $this->db->escape($input_name);$sql = "INSERT INTO users (name) VALUES($name)";$this->db->query($sql); - 注意:
escape()返回带引号的字符串(如'O\'Reilly'),不可再包一层引号
排查输出结果是否真被转义
有时显示异常是前端或 JSON 输出导致,而非数据库存储问题:
- 查数据库实际存入内容(用 phpMyAdmin 或命令行),确认是否多出反斜杠
- 用
var_dump($row['field'])查原始数据,避免视图中htmlentities()或json_encode()二次转义 - CI 3 的
global_xss_filtering若开启,会对 POST/GET 全局过滤,可能影响原始输入(不推荐开启)











