我想利用Codeigniter中Active Record的自我安全性。
要求是:
我在CI中有以下代码:
$this->db->select('sno');
$this->db->from('table1');
$this->db->where("cid",$cid);
$subquery=$this->db->get_compiled_select();
$this->db->select("pid")->from("table2");
$this->db->group_start();
$this->db->group_start();
$this->db->where("col1 <",$cin);
$this->db->where("col2 >",$cin);
$this->db->group_end();
$this->db->or_group_start();
$this->db->where("col1 <",$cout);
$this->db->where("col2 >",$cout);
$this->db->group_end();
$this->db->or_group_start();
$this->db->where("col1 >",$cin);
$this->db->where("col1 <",$cout);
$this->db->group_end();
$this->db->or_group_start();
$this->db->where("col1",$cin);
$this->db->or_where("col2",$cout);
$this->db->or_where("col1",$cout);
$this->db->or_where("col2",$cin);
$this->db->group_end();
$this->db->or_group_start();
$this->db->where("col2 >",$cin);
$this->db->where("col2 <",$cout);
$this->db->group_end();
$this->db->group_end();
$this->db->where_in("col3",$subquery);
$sbquery = $this->db->get_compiled_select();
$this->db->from('table1');
$this->db->where("tid",$cid);
$this->db->where_not_in("cid",$sbquery);
$result=$this->db->get_compiled_select();
var_dump($result);
exit;
此代码显示以下查询(作为var_dump的结果):
SELECT * FROM `table1` WHERE `tid` = '6' AND `cid` NOT IN('SELECT `pid`\nFROM `table2`\nWHERE (\n (\n`col1` < \'2018-12-10\'\nAND `col2` > \'2018-12-10\'\n )\nOR (\n`col1` < \'2018-12-16\'\nAND `col2` > \'2018-12-16\'\n )\nOR (\n`col1` > \'2018-12-10\'\nAND `col1` < \'2018-12-16\'\n )\nOR (\n`col1` = \'2018-12-10\'\nOR `col2` = \'2018-12-16\'\nOR `col1` = \'2018-12-16\'\nOR `col2` = \'2018-12-10\'\n )\nOR (\n`col2` > \'2018-12-10\'\nAND `col2` < \'2018-12-16\'\n )\n )\nAND `col3` IN(\'SELECT `sno`\\nFROM `table1`\\nWHERE `cid` = \\\'6\\\'\')')
当我使用以下代码(最后三行代码)时,这将导致错误的结果:
$result=$this->db->get()->result();
var_dump($result);
exit;
如果我直接在SQL中命中相同的查询,则会得到相同的错误结果。
但是,如果我删除斜杠,单引号,换行符和其他特殊字符,以直接在sql中命中重写的查询,我将获得非常准确的结果。
SELECT * FROM `table1` WHERE `tid` = '6' AND `cid` NOT IN(SELECT `pid` FROM `table2` WHERE ((`col1` < '2018-12-10' AND `col2` > '2018-12-10') OR (`col1` < '2018-12-16' AND `col2` > '2018-12-16') OR (`col1` > '2018-12-10' AND `col1` < '2018-12-16') OR (`col1` = '2018-12-10' OR `col2` = '2018-12-16' OR `col1` = '2018-12-16' OR `col2` = '2018-12-10') OR (`col2` > '2018-12-10' AND `col2` < '2018-12-16')) AND `col3` IN(SELECT `sno` FROM `table1` WHERE `cid` = '6'))
请提出解决方案。
答案 0 :(得分:1)
在活动记录子查询上添加FALSE
作为第三个参数,以使语句不会被转义。
从更改:
$this->db->where_in("col3",$subquery);
...
$this->db->where_not_in("cid",$sbquery);
至:
$this->db->where_in("col3",$subquery,FALSE);
...
$this->db->where_not_in("cid",$sbquery,FALSE);