【问题标题】:real_escape_string not cleaning up entered textreal_escape_string 不清理输入的文本
【发布时间】:2013-08-10 16:07:19
【问题描述】:

我认为在将 HTML 表单输入到 mySQL 数据库之前“清理”传入数据的正确方法是在 PHP 脚本中对其使用real_escape_string,如下所示: p>

$newsStoryHeadline = $_POST['newsStoryHeadline'];
$newsStoryHeadline = $mysqli->real_escape_string($newsStoryHeadline);
$storyDate = $_POST['storyDate'];
$storyDate = $mysqli->real_escape_string($storyDate);
$storySource = $_POST['storySource'];
$storySource = $mysqli->real_escape_string($storySource);
// etc.

一旦完成,您可以像这样将数据插入数据库:

$mysqli->query("INSERT INTO NewsStoriesTable (Headline, Date, DateAdded, Source, StoryCopy) VALUES ('".$newsStoryHeadline."', '".$storyDate."', '".$dateAdded."', '".$storySource."', '".$storyText."')");

所以我认为这样做可以清除您提交的文本中可能出现的所有不可见的“垃圾”字符。

但是,我只是将从网页复制的一些文本粘贴到我的 HTML 表单中,单击“提交”——它运行上述脚本并将该文本插入到我的数据库中——但是当我阅读该文本时 返回 从数据库中,我发现这段文本确实 中仍然有垃圾字符,例如–
当然,这些垃圾字符导致我编写的 PHP 脚本检索数据库中的信息崩溃。

那我做错了什么?

是使用real_escape_string 不是到这里的方式吗?还是我应该将它与其他东西结合使用? 或者,在从 mySQL 数据库读取数据时,我应该做些什么(比如转义)?

(我应该提一下,我是一名 Objective-C 开发人员,而不是 PHP/mySQL 开发人员,但不幸的是,我被赋予了这项任务来做一些数据库工作——因此我的问题是……) 谢谢!

【问题讨论】:

  • 一方面,您应该使用参数化查询而不是real_escape_string。您是否为页面正确设置了字符集?
  • 嗯,不太清楚您所说的“您是否正确设置了字符集”是什么意思——该语句会是什么样子? (我应该提一下,我是一名 Objective-C 开发人员,而不是 PHP/mySQL 开发人员,但不幸的是,我被赋予了这个任务来做一些 DB 的东西......)
  • 你从哪里得到“清理”“垃圾字符”的想法?
  • 我知道它们是“垃圾”,因为它们在原始文本中可见 - 但在检索时突然出现。这就是我对“垃圾”的看法 :-) 我假设它们正在格式化类型字符?无论哪种方式,它们都会导致我的 PHP 脚本崩溃,所以无论我们是否称它们为“垃圾”,我只需要了解如何处理它们 :-) 那么,有什么想法吗?
  • @sirab333 <meta charset="utf-8"> 在您的<head> 中。

标签: php mysql database mysqli mysql-real-escape-string


【解决方案1】:

你的假设是错误的。 mysqli_real_escape_string 的唯一目的是转义某些字符,以便可以在 MySQL string literal 中安全地使用生成的字符串。就是这样,不多也不少。

结果应该是准确地保留了传递的数据,包括“垃圾”。如果您不希望数据库中出现“垃圾”,则需要在将其传递给 MySQL 之前对其进行检测、验证或过滤。

在您的情况下,“垃圾”似乎是由于不同的字符编码:您输入的数据似乎是用 UTF-8 编码的,而它后来使用Windows-1250 显示。在这种情况下,字符 (U+2013) 将使用 UTF-8 中的 0xE28093 编码,这将表示 Windows-1250 中的三个字符 âProperly declaring the document’s encoding 可能会解决这个问题。

【讨论】:

  • 好的,我尝试通过将echo "<head><?xml version="1.0" encoding="UTF-8"?></head> 放入我的代码来解决编码问题 - 但它仍然无法正常工作。我把它放在查询数据库的 PHP 脚本中(通过SELECT * FROM NewsStoriesTable) ... etc 然后循环遍历结果集的 ROWS 并将所有内容作为 XML 回显。它仍然失败并给我错误。但是当我手动进入 mySQL 数据库和从包含 – 的条目中删除它,一切都恢复正常:我的 PHP 查询运行并生成良好、无错误的 XML。这是否更能说明问题?
  • @sirab333 XML 声明首先出现,甚至在文档类型声明之前。也首选send the content encoding via HTTP header。而关于数据库,那里的数据仍然可能被正确编码,但只是显示错误的字符编码。但我们只会知道您是否可以提供该数据的十六进制转储。
【解决方案2】:

消毒是一个棘手的主题,因为根据上下文,它永远不会意味着相同的事情。 :)

real_escape_string 只是确保您的数据可以包含在请求中(当然是在引号内),而不会更改请求的“含义”。

manual page 解释了函数的真正作用:它转义 nul 字符、换行符、回车、单引号、双引号和“Control-Z”(可能是 SUBSTITUTE 字符)。所以它只是在这些字符之前插入一个反斜杠。

就是这样。它“清理”字符串,因此可以在请求中原封不动地传递它。但它不会从任何其他角度对其进行清理:用户仍然可以传递例如 HTML 标记或“奇怪”字符。您需要根据输出格式(大多数情况下是 HTML,但 HTTP 不限于 HTML 文档)以及您想让用户做什么来制定规则。

如果您的代码无法处理某些字符,或者如果它们在输出格式中具有特殊含义,或者如果它们导致您的输出以某种方式出现“损坏”,您需要自行转义或删除它们。

您可能会对htmlspecialchars 感兴趣。控制字符通常不是 HTML 的问题。如果您的输出编码与您的输入编码相同,它们将不会显示,因此不会成为您的用户的问题(嗯,可能是 W3C 验证器)。如果您认为是,请创建自己的函数来检查并删除它们。

【讨论】:

  • 好的,这说明了一些事情。我会研究html_special_chars - 但这对XML 有帮助吗?因为这就是我想要得到的:好的、“健康的”XML。我的最终目标是简单地在 mySQL 数据库上运行一些查询 - 通过 PHP 脚本 - 并让该脚本将查询结果输出为 XML。大多数情况下,这工作得很好,但是每次 PHP 脚本遇到这些“垃圾”字符时,它们都会导致它崩溃并停止生成 XML。我得到错误。但它不是我所追求的 HTML - 只是 XML。让我知道这是否能让您更好地了解如何提供帮助 - 或者我应该在哪里寻找信息
  • 您可以在flagshtmlspecialchars 位掩码中传递ENT_XML1(对不起,我打错了函数名,该死的PHP 函数不连贯)。我不确定它会有什么不同,因为手册页中描述的替换似乎足以清理数据以放入 XML 元素中。也就是说,您可能应该将此类数据放在 <![CDATA[ ... ]]> 括号中,以便 XML 解析器将其视为原始字符串。
猜你喜欢
  • 1970-01-01
  • 2019-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2010-12-11
相关资源
最近更新 更多