3

PHP 在默认情况下使用“魔术引号”,但因此受到了很多批评。我知道它将在 PHP 的下一个主要版本中禁用它。

虽然反对它的论点是有道理的,但我不明白的是为什么不只使用 HTML 实体来表示引号而不是剥离和删除斜杠?毕竟,绝大多数 mySQL 用于输出到 Web 浏览器?

例如,' 使用而不是 ' 并且它根本不会影响数据库。

另一个问题,为什么 PHP 不能只为每个版本的 PHP 设置配置,带有这个标签 <?php4 或 <?php5 以便可以为这些版本加载适当的解释器?

只是好奇。:)

4

6 回答 6

9

&#039;如果您使用数据库内容的所有内容都是输出到网页,则放入数据库中的字符串列会很好。但事实并非如此。

最好在输出时转义输出。这是您唯一确定输出将发送到网页的唯一时间——而不是日志文件、电子邮件或其他目的地。

PS:默认情况下,PHP 已经在标准 php.ini 文件中关闭了魔术引号。它在 PHP 5.3 中已被弃用,并且在 PHP 6.0 中将完全从该语言中删除。

于 2009-08-26T04:01:24.660 回答
5

这是一个很好的理由,主要是为了回应您自己发布的答案:使用htmlspecialchars()htmlentities() 使您的 SQL 查询安全。这就是mysql_real_escape_string()的用途。

您似乎在假设只有单引号和双引号字符会造成问题。MySQL 查询实际上容易受到数据中的\x00\n\r\'和字符的"影响。\x1a如果您没有使用准备好的语句或mysql_real_escape_string(),那么您有一个 SQL 注入漏洞。

htmlspecialchars()并且htmlentities()不要转换所有这些字符,因此您无法使用这些功能使您的查询安全。为此,addslashes()也不会使您的查询安全!

其他较小的缺点包括其他海报已经提到的关于 MySQL 并不总是用于 Web 内容的事实,以及您正在增加数据所需的存储量和索引空间这一事实(考虑一个字节的存储空间作为报价)字符,而不是其实体形式的六个或更多字节的存储空间)。

于 2009-08-26T04:56:06.140 回答
2

我只会回答你的第一个问题。

无论如何,验证输入是一种错误的方法,因为重要的不是输入,问题在于它的使用位置。PHP 不能假设 MySQL 查询的所有输入都会输出到 HTML 实体有意义的上下文中。

很高兴看到 magic_quotes 正在运行;这是 PHP 出现许多安全问题的原因,很高兴看到他们采用新方法 :)

如果您针对您正在工作的上下文重新构建验证方法以在 OUTPUT 上进行验证,那么您将帮自己一个大忙。只有您作为程序员才能知道这一点。

于 2009-08-26T03:56:53.733 回答
1

MySQL 不转换'&#039;的原因&#039; 是不是 '. 如果您想将数据转换为输出,您应该在视图层执行此操作,而不是在您的数据库中。htmlentities在你回声之前/当你回声时打电话真的不是很难。

于 2009-08-26T03:57:57.910 回答
0

谢谢大家。如果我将引号更改为 HTML 实体而不是向它们添加斜杠,我必须真正考虑您的意思以及它可能产生的影响,但同样,这不是实际上也改变了输出/输入吗?

我想不出为什么我们不能或不应该为 mySQL 使用 HTML 实体,只要我们明确所有数据都是使用 HTML 实体编码的。毕竟,我的论点是基于这样一个事实,即大多数 mySQL 用于输出到 HTML 浏览器,以及 ' 和 " 和 / 会严重损害 mySQL 数据库的事实。所以,编码 ' 和" 和 / 作为 HTML 实体,然后将它们作为 INSERT 查询发送?此外,我们正在使用 XML,那么在访问已经在 HTML 实体中编码的数据时,为什么要浪费时间编写 htmlentities、stripslashes 和 addslashes?

于 2009-08-26T04:25:49.057 回答
0

您不能只转换'&#039;. 想一想:当你想存储字符串“ &#039;”时会发生什么?如果您存储&#039;,那么当您加载页面时,它将显示'而不是&#039;.

所以现在您必须转换所有 HTML 实体,而不仅仅是引号。然后你开始陷入各种奇怪的转换问题。最简单的解决方案是将真实数据存储在数据库中,然后您可以随意显示它。您可能希望使用实际引号 - 在大多数情况下"'不要在标签括号之外造成任何伤害。

有时您可能希望将实际的 HTML 存储在字段中并以原始方式显示(只要在输入/输出过程中对其进行检查和清理。

于 2009-08-26T12:28:14.120 回答