如何确保用户输入的包含国际字符的数据不会损坏?

2022-08-30 21:11:31

经常发生诸如é之类的字符被转换为é的情况,即使MySQL DB,表和字段的排序规则设置为utf8_general_ci也是如此。页面的“内容类型”中的编码也设置为 UTF8。

我知道utf8_encode/解码,但我不太确定在哪里以及如何使用它。

我已经阅读了“绝对最低限度每个软件开发人员绝对,肯定必须了解Unicode和字符集(没有借口!)”一文,但我需要一些MySQL / PHP特定的指针。

如何确保用户输入的包含国际字符的数据不会损坏?


答案 1

在第一次看 http://www.nicknettleton.com/zine/php/php-utf-8-cheatsheet 我认为缺少一件重要的事情(也许我忽略了这一点)。根据您的MySQL安装和/或配置,您必须设置连接编码,以便MySQL知道您在客户端(意味着MySQL连接的客户端,应该是PHP脚本)上期望的编码。您可以通过手动发出

SET NAMES utf8

在您发送到MySQL服务器的任何其他查询之前查询。

如果您在PHP端使用PDO,则可以将连接设置为在每次(重新)连接时自动发出此查询,方法是使用

$db=new PDO($dsn, $user, $pass);
$db->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES utf8");

初始化数据库连接时。


答案 2

排序规则和字符集不是一回事。您的归类需要匹配字符集,因此,如果您的字符集是 utf-8,则归类也应该匹配。选择错误的排序规则不会弄乱你的数据 - 只是让字符串比较/排序工作错误。

也就是说,有几个地方,你可以在PHP中设置字符集设置。如果可能的话,我建议您始终使用utf-8。需要指定字符集的位置包括:

  • 数据库。这可以在数据库、表和字段级别进行设置,甚至可以在每个查询级别进行设置。
  • PHP 和数据库之间的连接。
  • HTTP 输出;确保 HTTP 标头指定 utf-8。您可以在PHP和Apache中设置默认值,也可以使用PHP的head函数Content-Type
  • HTTP 输入。通常,表单将使用与提供页面时相同的字符集提交,但为了确保这一点,应指定 accept-charset 属性。还要确保URL是utf-8编码的,或者避免在url中使用非ascii字符(和GET参数)。

utf8_encode/解码函数的名称有点奇怪。它们专门在 latin1 (ISO-8859-1) 和 utf-8 之间转换。如果应用程序中的所有内容都是 utf-8,则不必过多地使用它们。

关于utf-8和PHP至少有两个陷阱。首先,PHP的内置字符串函数期望字符串是单字节的。对于很多操作来说,这并不重要,但这意味着你不能依赖strlen和其他功能。此页面上有一个很好的限制。通常,这不是一个大问题,但是特别是在使用3方库时,您需要注意事情可能会因此而爆炸。一种选择是使用mb_string扩展,该扩展可以选择用utf-8感知的替代方案替换所有麻烦的函数。它仍然不是100%防弹解决方案,但它在大多数情况下都有效。

另一个问题是,某些 PHP 安装仍然打开了magic_quotes设置。这个问题与utf-8正交,但可能导致一些挠头。为了你自己的理智而把它关掉。


推荐