遇到mysqli查询问题 - 特别是WHERE stoname=
子句。
这不起作用:
$result = @mysqli_query($dbc, "SELECT * FROM thedb WHERE coname='{$_SESSION['user']}' AND stoname='{$_SESSION['store']}' ");
如果我回显$_SESSION['store']
,那么它打印为o\'store
,与数据库中的内容相匹配。然而,这不起作用。
但是,如果我回显mysqli_real_escape_string($dbc,($_SESSION['store']))
,那么它会打印o\\\'store
,这不是数据库中的内容。但它确实有效。
$result = @mysqli_query($dbc, "SELECT * FROM thedb WHERE user='{$_SESSION['user']}' AND stoname='".mysqli_real_escape_string($dbc,($_SESSION['store']))."' ");
我接受我有工作代码,但我很困惑为什么会这样。任何人都可以解释我做了什么/做错了什么?感谢
答案 0 :(得分:2)
如果您的表格确实包含o\'store
,则mysqli_real_escape_string()
已正确完成其工作。函数的目的是转义字符串以安全包含在SQL语句中,而不是与表中实际存在的字符完全匹配。
表值包含字面\'
。当您在SQL语句中直接使用该值时,反斜杠被误解为作为'
的转义字符,而不是表格中显示的文字\
。因此,查询不会产生任何结果,因为执行的SQL语句是:
# MySQL sees only an escaped ' and no \
SELECT * FROM thedb WHERE coname='something' AND stoname='o\'store'
...意味着实际比较的stoname
的值只有o'store
而没有\
,因为\
已被MySQL作为转义字符丢弃。
所以mysqli_real_escape_string()
会产生一个有两处变化的值。
首先,原始字符串中的文字'
被反向转义为\'
,以便在SQL中使用。
然后,字符串中已有的文字\
本身就会被反斜杠转义,因此它可以被MySQL理解为文字字符,而不是转义字符。这导致\\
。结合转发的\'
,您现在拥有\\\'
。
MySQL收到该字符串\\\'
,并且能够在每个字符串之前丢弃额外的\
转义字符后将其正确解释为一个文字'
,后跟一个文字\
。条件与列的实际值匹配,您的查询成功。
# MySQL sees an escaped \ followed by an escaped '
SELECT * FROM thedb WHERE coname='something' AND stoname='o\\\'store'
我们不太了解你的桌子最初如何获得它的价值,但我有一种预感,它是以逃脱的形式存储的。如果字符串o\'store
最初为o'store
而没有\
,则表示已在表格中插入了转义值。通常不会这样做,这是不可取的。在插入数据时正确使用mysqli_real_escape_string()
应该存储原始字符串而不是转义字符串。只有在构造SQL语句时才会进行转义。