CodeIgniter中like()方法正确写法为$this->db->like('field_name', 'keyword'),字段名在前、关键词在后,支持'both'(默认)、'before'、'after'三种匹配模式,关键词中%和_需手动转义以防注入。

CodeIgniter 2.x 中 like() 方法的基本写法
CodeIgniter 2.x 的 Query Builder(Active Record)提供了 like() 方法做模糊查询,但它的参数顺序和行为容易出错。最常见的是把字段名和值的位置搞反,导致 SQL 报错或查不到数据。
正确写法是:$this->db->like('field_name', 'keyword') —— 字段名在前,关键词在后。如果只传一个参数,比如 $this->db->like('keyword'),CI 会默认对所有字段做 LIKE '%keyword%'(不推荐,性能差且不可控)。
- 支持三种匹配模式:
'both'(默认,前后加 %)、'before'(%keyword)、'after'(keyword%) - 例如:
$this->db->like('title', 'ci', 'both')→WHERE title LIKE '%ci%' - 注意:关键词中的
%和_不会被自动转义,若用户输入含这些字符,需手动过滤或用escape_like_str()
CodeIgniter 3.x+ 中 like() 的兼容性变化
CI 3.x 保留了 like(),但底层 SQL 构建更严格,尤其在链式调用中,or_like() 和 not_like() 的分组逻辑容易被忽略——它们不会自动加括号,多个 or_like() 会平铺在 WHERE 后,可能破坏预期的逻辑优先级。
- 错误示范:
$this->db->like('a', 'x')->or_like('b', 'y')→WHERE a LIKE '%x%' OR b LIKE '%y%'(没问题) - 但混合使用时:
$this->db->where('status', 1)->or_like('name', 'admin')→ 实际生成WHERE status = 1 OR name LIKE '%admin%',常被误以为是WHERE status = 1 AND (… OR …) - 解决办法:用
group_start()显式包裹:$this->db->where('status', 1)->group_start()->like('name', 'adm')->or_like('email', 'adm')->group_end()
手写 LIKE 拼接时如何防注入
绕过 Query Builder、直接用 where() 拼字符串(如 $this->db->where("name LIKE '%{$keyword}%'"))是最危险的写法,极易引发 SQL 注入。CI 提供了两个关键工具来安全处理:
-
$this->db->escape_like_str($user_input):对%、_、\转义,并返回已加引号的字符串(注意:它自带单引号) - 所以不要这样写:
"name LIKE '%" . $this->db->escape_like_str($kw) . "%'"(会导致双重引号) - 正确姿势:
$this->db->where("name LIKE '%" . $this->db->escape_like_str($kw) . "%'")或更稳妥地交给like()自动处理 - 若必须用通配符动态控制,先用
str_replace()清洗用户输入中的%和_,再进like()
自定义类中封装模糊查询方法的实用建议
在模型或服务类里封装 like 查询时,别只图方便把整个 $_GET 循环塞进 like()。字段是否允许模糊、是否需要全匹配、是否要忽略大小写(MySQL 默认不区分,但 collation 可能影响),都得提前约定。
- 示例封装:
public function search_by_keywords($keywords, $fields = ['title', 'desc']) { ... },内部遍历$fields并逐个调用like() - 避免在
like()中传入空字符串或 null,CI 2.x 会生成LIKE '%%',部分 MySQL 版本可能报 warning;CI 3.x+ 更严格,建议先if (!empty($kw)) { $this->db->like(...); } - 性能敏感场景下,
like('%xxx')无法走索引,而like('xxx%')可以——如果业务允许前缀匹配,优先用'after'模式
真正麻烦的不是语法怎么写,而是什么时候该用 like()、什么时候该换全文索引或 ES;还有就是开发时忘了字段加索引,上线后 LIKE '%keyword%' 扫全表,DBA 第一时间找上门。

















