【问题标题】:PHP mysql_real_escape_string() -> stripslashes() leaving multiple slashesPHP mysql_real_escape_string() -> stripslashes() 留下多个斜杠
【发布时间】:2010-12-04 02:03:24
【问题描述】:

我在使用 PHP/MySQL 转义/剥离字符串时遇到问题 - 似乎总是有多余的斜杠。


我们以下面的字符串为例:

<span style="text-decoration:underline;">underline</span>


向数据库添加字符串时,我使用mysql_real_escape_string() 对其进行转义,并将以下内容存储在数据库中(编辑:通过直接使用 mysql 应用程序查询数据库来检查):

<span style=\\\"text-decoration:underline;\\\">underline</span>


从数据库中读回时,我通过stripslashes() 传递字符串并返回以下内容:

<span style=\"text-decoration:underline;\">underline</span>


由于引号仍然被转义,它打破了html并且文本没有下划线。


  1. 为什么mysql_real_escape_string() 加了三个斜线,stripslashes() 去掉了两个斜线?我希望他们都添加/删除一个斜线。
  2. 如何防止这种情况发生?
  3. 我的处理方法正确吗?

【问题讨论】:

  • 注意:mysql()* 自 PHP 5.5.0 起已弃用,不推荐用于编写新代码,因为它会在未来被删除。相反,使用mysqliPDO

标签: php mysql-real-escape-string stripslashes


【解决方案1】:

最佳解决方案

在您的 php.ini 文件中,magic_quotes_gpc 指令可能设置为 on。出于安全原因,应禁用此功能。如果您无权访问 php.ini 文件(例如,在共享主机上),您始终可以使用 .htaccess 指令完成相同操作(假设这是一个 apache 服务器)。

在你的 php.ini 中

magic_quotes_gpc Off

在 .htaccess 文件中:

php_flag magic_quotes_gpc Off

为什么会这样?

发生这种情况的原因是由于以下逻辑过程。

  1. 需要转义的字符串被发送到服务器。
    • This is my string. It's awesome.
  2. Magic Quotes 在到达您的代码之前转义了撇号。
    • This is my string. It\'s awesome
  3. mysql_real_escape_string 现在有两个字符要转义,反斜杠 \\ 和撇号 \'
    • This is my string. It\\\'s awesome
  4. 这个新的超级转义字符串存储在数据库中。
  5. 当从数据库中检索字符串时,它被传递给stripslashes。这将删除在步骤 3 中添加的两个转义,但由于其中一个反斜杠已被转义,stripslashes 认为它属于。
    • This is my string. It\'s awesome

当您将这些字符串重新提交到数据库时,这个问题真的会失控,因为每次反斜杠的数量都会成倍增加。

替代解决方案

一种快速简便的替代方法是在将字符串传递给mysql_real_escape_string 之前简单地删除magic_quotes 添加的斜线。

$str = stripslashes($_POST['str']);
$str = mysql_real_escape_string($str);

【讨论】:

  • “当你将这些字符串重新提交到数据库时,这个问题真的会失控,因为每次反斜杠的数量都会成倍增加。”是的,这开始发生了!
  • 很棒的答案,问题解决了。感谢您了解三个斜线的来源的逻辑,现在是有道理的。
【解决方案2】:

向数据库添加字符串时,我使用mysql_real_escape_string() 对其进行转义,并将以下内容存储在数据库中:

&lt;span style=\\\"text-decoration:underline;\\\"&gt;underline&lt;/span&gt;

不,不是。当您在 sql 查询中转义字符串时,它只是为了传输查询中的数据。数据库解析查询并将数据存储在数据库中,没有任何额外的斜线。因此,当您从数据库中检索数据时,您应该 对任何内容进行转义。这是一个常见的误解。

如果您发现输出中有多余的斜线,您可能打开了魔术引号。 Turn them off.

编辑:

mysql> create table foo (bar text) ;
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO foo (bar) VALUES ("<span style=\\\"text-decoration:underline;\\\">underline</span>");
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM foo;
+-------------------------------------------------------------+
| bar                                                         |
+-------------------------------------------------------------+
| <span style=\"text-decoration:underline;\">underline</span> | 
+-------------------------------------------------------------+
1 row in set (0.00 sec)

如您所见,查询比数据库中显示的数据多一级转义,因此查询时它是如何出现的。在您的情况下,可能正在发生的事情是,您打开了魔术引号,然后在将字符串嵌入查询之前转义字符串。这会导致双重转义,篡改您的数据。正确的解决方案是像您一样继续转义字符串,但关闭魔术引号。 不要对从数据库中出来的数据做任何事情。请注意,需要先清理系统中已有的数据。

【讨论】:

  • 我已经使用 MySQL 应用程序直接在数据库上运行 SQL 查询,并返回上述字符串。所以在我看来, 用三个斜杠存储在数据库中。
  • 我不知道你的意思,但使用斜杠是因为你在代码中嵌入数据。就像 php 源代码中的字符串文字一样。相同的规则适用。
  • 需要转义数据的斜线不存储在数据库中。如果您看到斜线,那么它们一定是多余的。
【解决方案3】:

如果get_magic_quotes_gpc()在SERVER中是关闭的,那么只有我们可以使用

$data= mysql_real_escape_string($_POST['data']);

如果get_magic_quotes_gpc()在服务器中开启,我们必须使用

$data= mysql_real_escape_string(stripslashes($_POST['data']));

否则在您的数据中添加两个反斜杠。

另外一个解决方案是,如果我们只使用mysql_real_escape_string($_POST['data']);,我们可以使用stripslashes($data)同时从datadase获取数据

【讨论】:

  • stripslashes 和 mysql_real_escape_string 不能一起使用。前一个必须在脚本的最开始使用。清理所有数据,而不仅仅是一个去数据库。而后者必须在将字符串(并且仅字符串!)添加到查询之前立即使用。最后一个根本不是解决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 2011-03-29
  • 2012-11-11
  • 1970-01-01
相关资源
最近更新 更多