活动记录查询失败 - 从查询中转义引号

时间:2013-09-18 23:25:38

标签: sql codeigniter activerecord pyrocms

背景

  • 框架:Codeignighter / PyroCMS

我有一个存储产品列表的数据库,我的应用程序中有一个duplicate function,它首先查找常用的产品名称,以便它可以为重复的产品添加“suffix”值

我的产品模型类中的代码

$product = $this->get($id);

$count = $this->db->like('name', $product->name)->get('products')->num_rows();

$new_product->name = $product->name . ' - ' . $count;

在第二行,仅当$product->name包含引号时,应用程序才会失败。 我理解Codeignighter逃脱了所有字符串,所以我不知道为什么会出现这个错误。

所以我尝试使用MySQL转义字符串函数,但这也无济于事。

错误讯息

A Database Error Occurred

Error Number: 1064

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's Book%'' at line 3

SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'

的var_dump

以下是在相关行之前和之后对var_dump进行product->name的输出;

string 'Harry's Book' (length=12)

A Database Error Occurred

Error Number: 1064

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's Book%'' at line 3

SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'

3 个答案:

答案 0 :(得分:2)

让我们对此进行一些测试。

这是你在做什么

$count = $this->db->like('name', $product->name)->get('products')->num_rows();

我怀疑$product->name包含此内容。

哈利的书

我们知道这是来自您使用的数据库表。 在使用上面提到的查询的地方,它是用它包装的 单引号并产生这个结果。

SELECT * FROM `products` WHERE `name` LIKE '%Harry\\'s Book%'

正如你所看到的,它是逃避叛逆,告诉它不是字符串的结尾 因此,用两个斜线逃避它。一个是萎缩,另一个是单引号。

你要做的是 在将参数分配给查询之前,请用双引号将其包装。

$product_name   =   "$product->name";

现在将其传递给查询。

$count = $this->db->like('name', $product_name)->get('products')->num_rows();

输出将是

SELECT * FROM `products` WHERE `name` LIKE '%Harry\'s Book%'

你在这里看到差异。它现在包含单斜杠,记录将 被发现。

答案 1 :(得分:1)

其他答案对我没有用,但确实如此:

$count = $this->db->query("SELECT * FROM `default_firesale_products` WHERE `title` LIKE '".addslashes($product['title'])."'")->num_rows();

每当CI Active Record破坏您的查询时,您总是可以将原始查询放入其中并完全控制。

答案 2 :(得分:0)

尝试使用stripslashes()周围的$product->name

$count = $this->db->like('name', stripslashes($product->name))->get('products')->num_rows();

CI会自动转义具有有效记录的字符,但我敢打赌,如果您之前通过CI中的活动记录输入了该字符,则它已经被转义。所以现在它正在进行双重逃避。

更新:在查询之前,您可能还想尝试添加以下内容:

$this->db->_protect_identifiers = FALSE;

上次尝试:尝试以这种方式查询,因为似乎like有效记录导致错误:

$like = $product->name;
$this->db->query("SELECT * FROM `products` WHERE `name` LIKE '%$like%'");
相关问题