SQL 中的 PHP 报价 [已关闭]

PHP quotes in SQL [closed]

提问人:Simo Pelle 提问时间:2/14/2020 最后编辑:Simo Pelle 更新时间:2/27/2021 访问量:101

问:


这个问题是由一个错别字或一个无法再重现的问题引起的。虽然类似的问题可能在这里成为主题,但这个问题的解决方式不太可能帮助未来的读者。

3年前关闭。

为什么此代码会产生错误

  $sql = "INSERT INTO accountlist VALUES (\"\", \"$user\", \"$pwd\", \"$mail\", \"$date\")";

而这个没有?

  $sql = "INSERT INTO accountlist VALUES ('', '$user', '$pwd', '$mail', '$date')";

我知道双引号处理变量,而单引号则不然,所以第一个选项应该是正确的,但事实恰恰相反!

PHP MySQL SQL 行情

评论

1赞 Jay Blanchard 2/14/2020
因为在拳头中,你忘记了连接。但是等等......
1赞 Jay Blanchard 2/14/2020
....Little Bobby您的脚本有 SQL 注入攻击的风险。即使逃脱绳子也不安全!
1赞 Jay Blanchard 2/14/2020
因此,您应该始终使用准备好的语句,这样您就再也不用担心查询中的引号了!
1赞 Jay Blanchard 2/14/2020
mysqli_escape_string() 不会阻止 SQL 注入。有办法解决它。
1赞 Stephen M Irving 2/14/2020
@JayBlanchard 不幸的是,由于我们的慈善事业,我们现在必须涉足像这样的问题浪潮,以及那些询问如何在 css 中垂直居中 div 的问题。

答:

3赞 Jay Blanchard 2/14/2020 #1

因为在第一个中,您忘记了连接,从而导致错误。但是等等......

....您应该始终使用准备好的语句,这样您就再也不用担心查询中的引号了!

在第二个查询中,PHP 将在单引号中插入变量,因为整个查询被双引号括起来。

Little Bobby您的脚本有 SQL 注入攻击的风险。即使逃脱绳子也不安全!

1赞 Mike Robinson 2/14/2020 #2

他们说的是死钱......而且也容易得多!

您的查询将变为:

INSERT INTO accountlist VALUES ("", ?, ?, ?, ?)

符号(请注意,没有用引号括起来)是参数。?

现在,每次执行查询时,您都会提供一个包含四个值的数组,这些值将在语句中从左到右替换。这些值可以是任何值,您不必关心引号等,因为它们不是 SQL 的一部分。相反,参数是输入。

如果你必须做“一大堆”,比如说数千或数百万次,你只准备一次语句,然后根据需要多次执行准备好的语句,每次提供不同的值数组作为输入。

还有很多库可以让你按名称指定参数,给出命名值的哈希值,例如

INSERT INTO accountlist VALUES ("", :user:, :pwd:, :mail:, :date:)

{ 'user' => 'fred', 'pwd' => 'secret', 'mail' => '[email protected]', 'date' => today() }

...该库将其转换为有效的 SQL 语句,如上所示。

更安全,更不麻烦,效率明显更高。

1赞 Bill Karwin 2/14/2020 #3

要回答您的问题,而不是继续讨论查询参数...

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 本身。

这就是为什么有些人可能听起来对你问这个问题感到不耐烦。这是一个非常初级的问题,表明你对编程语言的阅读还不够,你希望社区为你提供个性化的辅导,让你自己获得概念。

评论

0赞 Simo Pelle 2/14/2020
此外,这是我第一次接近服务器端世界(我现在有点迷失方向),也是我第一次以这种方式运行命令,所以这里为什么我提出这样的问题 stackoverflow.com/questions/60213796/unique-signup-method
0赞 Simo Pelle 2/14/2020
无论如何,感谢您的回答,现在更清楚了!
0赞 Salman A 2/14/2020
@temp 即使在C++中,您也需要将开盘与关盘相匹配。""
0赞 Simo Pelle 2/14/2020
@SalamanA如果没有单关闭和双关闭,你甚至永远不会面对另一个引用中引用的问题,而且在C++中,我从来没有遇到过像*为另一种语言运行命令“这样的事情(我什至不知道你是否可以做这样的事情)
0赞 Bill Karwin 2/14/2020
@Temp,这里有一些阅读给你:en.cppreference.com/w/cpp/language/escape