CodeIgniter查询构建器问题:逗号列完整项匹配与子查询转义
解决CodeIgniter查询构建器的两个常见问题
问题1:查询逗号分隔列中的完整匹配项
想要匹配逗号分隔列里的完整独立项,最稳妥的方式是给列值和搜索词都前后加上逗号,这样就能避免部分匹配(比如不会把PER_UNIT和PER_UNIT_DISCOUNT搞混)。用CodeIgniter查询构建器可以这么实现:
基础写法(带SQL注入防护)
$search_term = 'PER_UNIT'; // 你的搜索词 $safe_pattern = "%," . $this->db->escape_like_str($search_term) . ",%"; $this->db->select('*'); $this->db->from('your_table'); // 自定义WHERE条件,使用绑定参数避免转义问题 $this->db->where("CONCAT(',', RTRIM(rule), ',') LIKE ?", $safe_pattern); $result = $this->db->get()->result();
关键点说明:
RTRIM(rule):清理列值末尾的空格,避免空格干扰匹配结果escape_like_str():转义搜索词里的特殊字符(比如%、_),防止SQL注入- 使用绑定参数
?:比直接拼接字符串更安全,也能减少框架自动转义的误判
问题2:子查询中LIKE条件被自动添加反引号的解决办法
你遇到的反引号问题,是因为CodeIgniter查询构建器把PER_UNIT误当成了数据库字段,自动给它加了标识符包裹。有两个简单的解决方式:
方法1:直接关闭from()的转义功能
在调用from()时传入第二个参数FALSE,告诉框架不要转义你传入的子查询字符串:
$this->db->from("(SELECT * FROM acme WHERE CONCAT(',', RTRIM(rule), ',') LIKE '%,PER_UNIT,%') AS acme_filtered", FALSE);
这样框架就不会修改你子查询里的任何内容,反引号自然就消失了。
方法2:用查询构建器构建子查询(更推荐)
手动写字符串子查询容易出问题,不如用CodeIgniter的子查询能力来构建,既规范又安全:
// 先构建子查询 $sub_query = $this->db->select('*') ->from('acme') ->where("CONCAT(',', RTRIM(rule), ',') LIKE '%," . $this->db->escape_like_str('PER_UNIT') . ",%'", NULL, FALSE) ->get_compiled_select(); // 主查询中使用子查询 $this->db->from("($sub_query) AS acme_filtered"); $final_result = $this->db->get()->result();
这种方式既利用了框架的安全机制,又能彻底避免转义误判的问题。
内容的提问来源于stack exchange,提问作者Angga Ari Wijaya
相关产品推荐
相关产品推荐

