php - 配置更改后,MySQL 数据库中的 UTF-8 字符串变得困惑

标签 php mysql utf-8

我有一个带字符串的 MySQL,我搁置了一段时间。现在我再次拿起它,我发现所有的特殊字符都搞砸了。我的 ISP 已将服务器移植到另一台机器上,我怀疑这可能是它发生的时候。

数据库由 PHP 脚本填充。一切都应该是 UTF-8,这就是数据库设置的内容。

然而,这是字符串现在的样子:

fête

这四个特殊字符应该是一个字符,ê,字符串应该是fête

现在看起来只是重新编码了两次,但这似乎不对。这四个十六进制字符是:

C3 83 C6 92 C3 82 C2 AA

这看起来很像 UTF-8,所以如果我们解码它,我们会得到

C3 3F C2 AA

这不完全是 UTF-8(因为 3F),但让我们再次解码它:

FF AA

这不是 UTF-8。

ê 字符是 EA,在 UTF-8 中,即 C3 AA

另一个示例:西类牙语倒置问号 (¿) 为 C8 83 E2 80 9A C3 82 C2,它解码为 C3 3F 82 BF,这又不是正确的 UTF-8(转换为 FF 82 BF)。 ¿ 的预期字符是 BF,即正确 UTF-8 中的 C2 BF

这里发生了什么?人物是怎么乱来的?更重要的是,我该如何修复它?

(旁注 - 新服务器要求我编写 mysql_set_charset("utf8"); 否则字符串也会被弄乱,尽管采用“UTF-8 as latin1”方式,而不是这种奇怪的时尚如上所示。)

长话短说:

  • 通过 PHP 脚本以 UTF-8 填充 MySQL 数据库
  • 休眠多年,服务器已迁移。
  • 现在字符乱七八糟,见上文。

最佳答案

C3 83 C6 92 C3 82 C2 AA

This looks very much like UTF-8, so if we decode it, we get

C3 3F C2 AA

这就是将字节序列视为 UTF-8,然后将其编码为 ISO-8859-1 时得到的结果。 3F?,它已作为替换字符包含在内,因为 UTF-8 C6 92 是 U+0192 ƒ 在 ISO-8859-1 中不存在。但它确实存在于 Windows 代码页 1252 Western European,一种与 ISO-8859-1 非常相似的编码;在那里,它是字节 0x83。

C3 83 C2 AA

再经过一轮 treat-as-UTF-8-bytes-and-encode-to-cp1252,你会得到:

C3 AA

最后是 ê 的 UTF-8。

请注意,即使您明确将非 XML HTML 页面作为 ISO-8859-1 提供,由于令人讨厌的历史原因,浏览器实际上也会使用 cp1252 编码。

不幸的是,MySQL 没有 cp1252 编码; latin1 是(正确地)ISO-8859-1。因此,您将无法通过转储为 latin1 然后重新加载为 utf8(两次)来修复数据。您必须使用可以另存为的文本编辑器处理脚本(或者例如在 Python file(path, 'rb').read().decode('utf-8').encode(' cp1252').decode('utf-8').encode('cp1252')).

关于php - 配置更改后,MySQL 数据库中的 UTF-8 字符串变得困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7861803/

相关文章:

php - magento 安装后使用旧数据库

mysql - #1115 - 未知字符集 : 'utf8mb4'

php - 我只需要检索登录用户的记录

php - select 命令在 php/mysql 中不起作用

mysql - UPDATE 可以用不同的方式写吗?

PHP导出到excel不显示UTF-8

url - utf-8 网址问题

php - DataTables:使用多个表、分组和 html 内容加速服务器端处理?

php - 异常:不允许序列化 'Closure'

MySQL 连接两个表