PHP mysql_real_escape_string() - > stripslashes()留下多个斜杠

时间:2009-10-05 20:48:21

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

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


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

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


在向数据库添加字符串时,我将使用mysql_real_escape_string()转义它,并将以下内容存储在数据库中(编辑:通过使用mysql app直接查询数据库来检查此内容):< / p>

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


从数据库中读回来时,我将字符串传递给stripslashes(),然后返回以下内容:

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


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


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

3 个答案:

答案 0 :(得分:81)

最佳解决方案

在你的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
  6. 当您将这些字符串重新提交到数据库时,每次反斜杠的数量都会增加时,这个问题就会失控。

    替代解决方案

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

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

答案 1 :(得分:3)

  

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

     

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

不,不是。在sql查询中转义字符串时,它只是在查询中传输数据。数据库解析查询并将数据存储在数据库中,而不需要任何额外的斜杠。因此,当您从数据库中检索数据时,您应该 unescape任何东西。这是一种常见的误解。

如果您发现输出中有多余的斜杠,则可能会启用魔术引号。 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)

正如您所看到的,查询比数据库中出现的数据还有一个转义级别,因此在查询时它会如何出现。在你的情况下,可能正在进行的是,你打开魔术引号然后在将它们嵌入查询之前转义字符串。这会导致双重逃逸,篡改您的数据。正确的解决方案是像你一样保持转义字符串,但关闭魔术引号。并且不会对数据进行任何操作,因为它来自数据库。请注意,系统中已有的数据需要先清理干净。

答案 2 :(得分:1)

如果SERVER中的get_magic_quotes_gpc()已关闭,那么我们只能使用

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

如果SERVER中有get_magic_quotes_gpc(),我们必须使用

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

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

另一个解决方案是,如果我们仅使用stripslashes($data)

,我们可以在从数据库获取时使用mysql_real_escape_string($_POST['data']);