提问人:Simo Pelle 提问时间:2/14/2020 最后编辑:Simo Pelle 更新时间:2/27/2021 访问量:101
SQL 中的 PHP 报价 [已关闭]
PHP quotes in SQL [closed]
问:
为什么此代码会产生错误
$sql = "INSERT INTO accountlist VALUES (\"\", \"$user\", \"$pwd\", \"$mail\", \"$date\")";
而这个没有?
$sql = "INSERT INTO accountlist VALUES ('', '$user', '$pwd', '$mail', '$date')";
我知道双引号处理变量,而单引号则不然,所以第一个选项应该是正确的,但事实恰恰相反!
答:
因为在第一个中,您忘记了连接,从而导致错误。但是等等......
....您应该始终使用准备好的语句,这样您就再也不用担心查询中的引号了!
在第二个查询中,PHP 将在单引号中插入变量,因为整个查询被双引号括起来。
Little Bobby 说您的脚本有 SQL 注入攻击的风险。即使逃脱绳子也不安全!
他们说的是死钱......而且也容易得多!
您的查询将变为:
INSERT INTO accountlist VALUES ("", ?, ?, ?, ?)
符号(请注意,没有用引号括起来)是参数。?
现在,每次执行查询时,您都会提供一个包含四个值的数组,这些值将在语句中从左到右替换。这些值可以是任何值,您不必关心引号等,因为它们不是 SQL 的一部分。相反,参数是输入。
如果你必须做“一大堆”,比如说数千或数百万次,你只准备一次语句,然后根据需要多次执行准备好的语句,每次提供不同的值数组作为输入。
还有很多库可以让你按名称指定参数,给出命名值的哈希值,例如
INSERT INTO accountlist VALUES ("", :user:, :pwd:, :mail:, :date:)
{ 'user' => 'fred', 'pwd' => 'secret', 'mail' => '[email protected]', 'date' => today() }
...该库将其转换为有效的 SQL 语句,如上所示。
更安全,更不麻烦,效率明显更高。
要回答您的问题,而不是继续讨论查询参数...
https://www.php.net/manual/en/language.types.string.php 解释了在带引号的字符串中使用引号字符的机制。
基本上,如果你的PHP字符串用 分隔,那么下一个字符就是字符串的末尾。"
"
但是,您可能希望在字符串中使用文字双引号字符,但不要结束字符串。为此,您可以在它前面放置一个反斜杠,如下所示:
$sql = "INSERT INTO accountlist VALUES (\"\", \"$user\", \"$pwd\", \"$mail\", \"$date\")";
然后,反斜杠双引号字符将成为字符串内容的一部分,而不是字符串末尾的分隔符。
但是双引号字符串中的单引号字符不会导致相同的歧义,因此不需要反斜杠。因此,以下操作不会出错:
$sql = "INSERT INTO accountlist VALUES ('', '$user', '$pwd', '$mail', '$date')";
解析器可以判断单引号不是它要查找的字符来结束双引号字符串。因此,这些单引号被解析为文字字符。
这在许多其他编程语言中的工作方式相同,例如 Java、C、C++、Ruby、Python、Perl,甚至 SQL 本身。
这就是为什么有些人可能听起来对你问这个问题感到不耐烦。这是一个非常初级的问题,表明你对编程语言的阅读还不够,你希望社区为你提供个性化的辅导,让你自己获得概念。
评论
"
"
评论
mysqli_escape_string()
不会阻止 SQL 注入。有办法解决它。