CodeIgniter中MySQL LIKE语句%符号自动转成&的原因咨询
嘿,我来帮你拆解这个问题——你遇到的'26/04'被自动转成'&/04%'的现象,核心原因主要有两个,咱们一步步梳理:
1. CodeIgniter的自动转义/HTML实体编码搞的鬼
CodeIgniter默认会开启全局XSS过滤或者HTML实体编码(尤其是当你从POST/GET获取数据,或者application/config/config.php里的global_xss_filtering设为TRUE时)。哪怕你手动给$userdob赋值为'26/04',如果后续操作中框架触发了自动转义逻辑,就可能把字符串里的特殊字符转成HTML实体,导致最终SQL里出现&/04%这种奇怪的内容。
另外,如果你是把生成的SQL语句输出到浏览器里查看,浏览器本身也会自动把&转成&,这会让你误以为SQL本身有问题,但实际执行的SQL可能是正常的——不过你说运行查询时出问题,那大概率是框架的自动转义影响了实际执行的SQL参数。
2. 直接拼接SQL的写法既危险又容易出问题
你现在直接把变量拼进SQL字符串的方式,不仅存在严重的SQL注入风险,还会让框架的自动转义机制无法正确工作,很容易出现参数被乱转义的情况。
解决方法,分两种情况:
首选:用CodeIgniter查询构建器重构查询
这是最安全、最省心的方式,框架会自动处理参数转义,完全避免你遇到的转义问题,代码也更清晰:
$userdob = '26/04'; $session_dob = $_SESSION['date_of_birth']; $current_user_id = $_SESSION['id']; // 构建查询 $this->db->select('*') ->from('users') ->where_not_in('userid', $current_user_id) ->like('user_location', $city_key) ->like('dob', $userdob) ->not_like('dob', $session_dob); // 执行查询并获取结果 $query = $this->db->get(); $users = $query->result();
用查询构建器的好处:
- 自动帮你处理LIKE的通配符和参数转义,不会出现莫名其妙的HTML实体
- 从根源上避免SQL注入
- 代码可读性和维护性都比直接拼接强太多
如果你非要用原生SQL拼接(不推荐)
那一定要手动用框架的转义方法处理每个参数,避免转义错误和注入:
// 对每个参数进行安全转义,包括LIKE的%通配符 $escaped_userdob = $this->db->escape('%' . $userdob . '%'); $escaped_session_dob = $this->db->escape('%' . $_SESSION['date_of_birth'] . '%'); $escaped_userid = $this->db->escape($_SESSION['id']); $escaped_city = $this->db->escape('%' . $city_key . '%'); // 拼接待执行的SQL $sql = "SELECT * FROM users WHERE userid NOT IN(" . $escaped_userid . ") AND user_location LIKE " . $escaped_city . " AND dob LIKE " . $escaped_userdob . " AND dob NOT LIKE " . $escaped_session_dob; // 执行查询 $query = $this->db->query($sql);
额外排查点
如果用了上面的方法还是有问题,建议检查application/config/config.php里的$config['global_xss_filtering'],如果它是TRUE,可以改成FALSE试试——全局过滤有时候会过度处理你的变量。另外,确保$_SESSION['date_of_birth']在赋值的时候没有被转义,比如从POST获取时要关闭XSS过滤:
$_SESSION['date_of_birth'] = $this->input->post('date_of_birth', FALSE);
内容的提问来源于stack exchange,提问作者MSP

