real_escape_string没有清理输入的文本

时间:2013-08-10 16:07:20

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

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

$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开发人员,但不幸的是我被赋予了这个任务来做一些数据库的东西 - 因此我的问题......) 谢谢!

2 个答案:

答案 0 :(得分:2)

你的假设是错误的。 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可能会解决这个问题。

答案 1 :(得分:1)

清理是一个棘手的主题,因为它根本不具有相同的意义。 :)

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

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

就是这样。它“清理”字符串,因此可以在请求中保持不变。但它并没有在任何其他观点下对其进行消毒:用户仍然可以传递HTML标记或“奇怪”字符。您需要根据输出格式制定规则(大部分时间是HTML,但HTTP不限于HTML文档),以及您希望用户做什么。

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

您可能会对htmlspecialchars感兴趣。控制字符通常不是HTML的问题。如果您的输出编码与输入编码相同,则不会显示它们,因此对您的用户来说不是问题(好吧,也许是W3C验证器)。如果您认为是,请自行检查并删除它们。