繁体   English   中英

htmlentities设置为“ UTF-8”时,图片未上传

[英]Images not uploading when htmlentities has 'UTF-8' set

我有一个表单,其中包括接受要上传的图像并将其粘贴到数据库中。 以前,我有一个过滤POSTed数据的函数,该函数基本上是:

function processInput($stuff) {
    $formdata = $stuff;
    $formdata = htmlentities($formdata, ENT_QUOTES);
    return "'" . mysql_real_escape_string(stripslashes($formdata)) . "'";
}

为了修复某些未正确转换的怪异实体时,我将功能更改为(更改的只是我在htmlentities中添加了“ UTF-8”位):

function processInput($stuff) {
        $formdata = $stuff;
        $formdata = htmlentities($formdata, ENT_QUOTES, 'UTF-8'); //added UTF-8
        return "'" . mysql_real_escape_string(stripslashes($formdata)) . "'";
    }

现在,图像将不会上传。

是什么原因造成的? 只需删除“ UTF-8”位,即可正确上传图像,但随后,用户放入系统中的某些MS Word实体就会显示为乱码。 到底是怎么回事?

**编辑:由于我不能做太多更改此野兽上的代码,因此我可以使用htmlspecialchars()而不是htmlentities()来贴上创可贴,这似乎至少使图像数据保持不变,同时转换了引号等内容,尖括号等。bobince的建议非常好,但是在这种情况下,我现在无法花费时间来修复该项目中的混乱旧版代码。 我处理的大多数内容都是面向对象的和基于框架的,但是现在我亲眼看到了人们谈论PHP中的“意大利面条式代码”时的意思。

function processInput($stuff) {
    $formdata = $stuff;
    $formdata = htmlentities($formdata, ENT_QUOTES);
    return "'" . mysql_real_escape_string(stripslashes($formdata)) . "'";
}

此函数表示字符串处理的基本误解,这是PHP程序员常见的一种。

SQL转义,HTML转义和输入验证是三个独立的函数,将在脚本的不同阶段使用。 一口气尝试全部完成是没有意义的。 当在脚本的其他部分中使用时,只会导致对任何一个进程“特殊”的字符变得混乱。 您可以尝试修改此功能,以尝试修复应用程序一部分中的错误,但会破坏其他功能。

为什么图像被扭曲? 好吧,目前还不清楚通过什么路径将图像数据从$_FILES临时上传文件传输到数据库。 如果在任何时候都涉及到此功能,它将完全破坏图像文件的二进制内容。 删除了反斜杠并转义了HTML……没有图像可以幸免。

  1. mysql_real_escape_string用于转义一些包含在MySQL字符串文字中的文本。 当使用插入的文本制作SQL字符串文字时,应始终仅将其使用, 而不应将其全局应用于输入。 因为输入中包含的某些内容不会立即或仅进入数据库。 例如,如果您echo输入值到HTML页面中的一个,你会发现你得到了一堆不必要的反斜线在它时,它包含了诸如字符' 这就是您最终得到充满反斜杠的页面的方式。

    (即使那样,参数化查询通常也比手动字符串黑客攻击和mysql_real_escape_string更好。它们会向您隐藏字符串转义的详细信息,以免您被它们混淆。)

  2. htmlentities用于转义包含在HTML页面中的文本。 应该在PHP的输出模板位中始终使用它。 在所有输入上全局运行它是不合适的,因为并非所有内容都将最终显示在HTML页面中或仅在HTML页面中显示,并且很可能首先将其转到您绝对不希望加载的数据库中的< & 垃圾使您的文本无法可靠搜索或子字符串化。

    (即使那样, htmlspecialchars通常也比htmlentities更可取,因为它只编码真正需要它的字符htmlentities将添加不必要的转义,除非您告诉它正确的编码,否则它也将完全弄乱您所有的非ASCII字符htmlentities几乎不应该使用。)

  3. 至于stripslashes ……好吧, 有时您需要将其应用到输入中,但是仅当启用了惯用的magic_quotes_gpc选项时。 当然,只有当您检测到magic_quotes_gpc处于打开状态时,您才应该一直应用它。 长期以来,它已被弃用,并且很容易消亡,因此,如果检测到错误消息已被打开,则可能同样有用。 然后,你可以扔掉整个processInput事情了。

总结一下:

  • 在启动时,做没有全球性的输入处理。 如果需要,您可以在此处进行特定于应用程序的验证,例如检查电话号码只是数字,还是从文本或其他内容中删除控制字符,但此处不应进行转义。

  • 当在其中使用字符串文字的SQL查询时,对字符串中的值使用SQL转义: $query= "SELECT * FROM t WHERE name='".mysql_real_escape_string($name)."'"; 您可以使用较短的名称定义一个函数,以进行转义以节省一些键入内容。 或者更可读地是参数化。

  • 使用来自输入或数据库或其他地方的字符串进行HTML输出时,请使用HTML转义,例如: <p>Hello, <?php echo htmlspecialchars($name); ?>!</p> <p>Hello, <?php echo htmlspecialchars($name); ?>!</p> 同样,您可以定义一个带有短名称的函数以echo htmlspecialchars以节省键入内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM