0

我有一些用户输入数据被放入 MySQL 数据库(根据 phpMyAdmin 为 5.5.8 版) - 我发现mysql_real_escape_string()在下面的示例中必须调用两次,否则不会将反斜杠添加到用户输入文本中,例如“SHE'S A伟大的船不是她”

当我尝试将那种类型的“包含引号的文本字符串”写入我的数据库时会出现问题——用户输入字符串被写入数据库时​​没有反斜杠——除非我调用mysql_real_escape_string()两次。

我使用 phpMyAdmin 查看新写入的数据库记录,并且用户的 text-string-with-quotes 在引号上没有转义(没有反斜杠)。如果我从数据库中读回该文本字符串,则不会转义引号,即。我不必调用stripslashes()来反转使用mysql_real_escape_string().

代码如下。当我调用 get_magic_quotes_gpc() 时,它显示它们已被禁用。

我的期望是这样的:如果用户输入一个文本字符串,如“SHE'S A GREAT BOAT ISN'T SHE” ——然后我在该用户输入文本上调用mysql_real_escape_string() 一次,并将其写入数据库,这 一次调用mysql_real_escape_string()创建如下所示的文本字符串:

\"她\'SA GREAT BOAT ISN\'T She\"

但是写入数据库的文本(见下文)显示没有转义,只是原始用户输入文本及其所有未转义的引号。

这是将用户文本字符串写入数据库的 PHP 代码:

// theUsersInputText contains "SHE'S A GREAT BOAT ISN'T SHE"
$theText = $_POST['theUsersInputText'];

$theDB = connectToDb();

  // THIS ALWAYS REPORTS THAT MAGIC QUOTES ARE DISABLED
if(get_magic_quotes_gpc())
echo "Magic quotes are enabled";
else
echo "Magic quotes are disabled";  

$theEscapedText =  mysql_real_escape_string($theText);
$newInsertQuery = "INSERT INTO " . "myDatabaseTable" 
        . " VALUES "
        . "('" . $theEscapedText . "')";

当我使用 phpMyAdmin 查看数据库时,文本字符串中没有斜线。当从数据库中检索这个字符串时——它看起来像这样: “SHE'S A GREAT BOAT ISN'T SHE”

这让我觉得我很容易受到注射攻击。

所以我通过添加第二个调用来修改上面的代码mysql_real_escape_string,现在当我查看数据库时,文本字符串最终看起来像这样:

\"她\'SA GREAT BOAT ISN\'T She\"

这是修改后的代码:

$theText = $_POST['theUsersInputText'];

  // NEW LINE OF CODE HERE
$theStrangelyUnescapedText =  mysql_real_escape_string($theText);    

$theDB = connectToDb();

  // THIS ALWAYS REPORTS THAT MAGIC QUOTES ARE DISABLED
if(get_magic_quotes_gpc())
showAlertBox("Magic quotes are enabled");
else
showAlertBox("Magic quotes are disabled");  


$theFinallyEscapedText =  mysql_real_escape_string($theStrangelyUnescapedText);
$newInsertQuery = "INSERT INTO " . "myDatabaseTable" 
        . " VALUES "
        . "('" . $theFinallyEscapedText . . "')";

经过以上,最后在phpMyAdmin中,当我查看刚刚写好的数据库记录时,文字看起来是这样的:

\"她\'SA GREAT BOAT ISN\'T She\"

为什么我要mysql_real_escape_string()在这里打两次电话?

4

2 回答 2

0

写成这样

$theEscapedText =  mysql_real_escape_string($theText);
$newInsertQuery = "INSERT INTO `myDatabaseTable`  VALUES ('$theEscapedText')";

我得到查询输出

INSERT INTO `myDatabaseTable` VALUES ('\"SHE\'S A GREAT BOAT ISN\'T SHE\"')

斜杠是为了使查询在语法上正确并尽量避免sql注入,在数据库中查询将存储原始文本

"SHE'S A GREAT BOAT ISN'T SHE"

作为旁注:Mysql_* 扩展自 PHP 5.5.0 起已弃用,并将在未来删除。相反,应该使用 MySQLi 或 PDO_MySQL 扩展。

一个有用的链接为什么我不应该在 PHP 中使用 mysql_* 函数

于 2013-08-08T04:30:39.040 回答
0

我决定使用 heredoc 并输出到文件来确定我第一次调用 mysql_real_escape_string() 的效果(如果有的话)。我使用了以下代码——从用户输入中读取了 php 变量“theTextWithManyQuotes”,它是一个文本字符串,例如“Isn't O'Malley's parents' children's “choices” atypical”

  $theTextWithManyQuotes = mysql_real_escape_string($_POST['userInput']);

  $html = <<<HEREDOC

  <!DOCTYPE html>
  <body>
    <textarea readonly name="adPreviewText" id="adPreviewText" rows="4" cols="60"
      style="border: none; border-style: none">$theTextWithManyQuotes</textarea>
  /body>
  </html>
HEREDOC;

file_put_contents("testfileonly", $html); 

然后我通过 file_put_contents() 将 $html 变量转储到一个文件中,并打开了“testfileonly”文件——反斜杠实际上存在于文本中。

我的猜测是,当我构建一个 mysql 查询字符串并且它包含通过一次调用 mysql_real_escape_string() 进行转义的转义文本字符串时,数据库会以某种方式“隐藏”反斜杠,以便在查看数据库记录。

我的heredoc内容在输出到文件时显示存在反斜杠这一事实向我证明,只需要一次调用 mysql_real_escape_string() ,并且 mysql 数据库不知何故没有显示(或剥离?)数据库记录中的反斜杠。当从数据库中读回数据时,不需要调用 stripslashes(),从数据库中读回时文本字符串中不存在反斜杠。

于 2013-08-08T16:33:32.577 回答