【发布时间】:2018-11-21 23:46:36
【问题描述】:
我正在将现有数据库迁移到另一台服务器。为了实现这一点,我使用 phpMyAdmin SQL 查询导出和导入了数据库。一切正常,除了一些 UTF-8 字符在网站中出现损坏。我使用相同的 PHP 代码获取它们(在不同的服务器上,但具有相同的 PHP 扩展和版本)。
我在新网站和数据库(新旧)上看到的字符串示例(使用 phpMyAdmin):péri-prothétique
我在旧网站péri-prothétique看到的字符串示例
如您所见,PHP 曾经以正确的方式自动对字符进行编码,即使这些字符在数据库中被损坏,但现在不再这样做了(即使我明确地 utf8_encode 或 utf8_decode 结果也不行)。我什至尝试在每个连接上强制$mysqli->set_charset("UTF8") 无济于事。
Web 服务器、数据库服务器、服务器连接、PHP 和表格都使用 UTF-8 或 utf8mb4 字符集和排序规则,并且设置方式与旧的相同。
我看到的唯一区别是新的数据库服务器是 MariaDB 而不是 MySQL,它的网络服务器是 nginx 而不是 Apache。
来自 phpMyAdmin 的新数据库规格图片:
旧数据库规格图片:
运行网站和 PHP 的新网络服务器规范(与旧的规范相同,但服务器不同): Apache 2.4 PHP 7.0
我怎样才能恢复原来的正确编码?为什么 PHP 不再自动解码它们了?
更新:
使用mb_detect_encoding 我看到新旧版本的 PHP 在查询结果中检测 ASCII 或 UTF-8,这取决于是否至少有一个 UTF-8 符号。
问题是在新版本中,PHP 不会正确显示 UTF-8 符号,即使它检测到字符串编码为 UTF-8。
更新 2:
感谢this question,我弄清楚了为什么我的条目被破坏了:双重编码是因为数据库排序规则是latin1_swedish_ci,而表排序规则是utf8_general_ci。
这并不能回答所想的问题,因为旧网站会自动“翻译”那些损坏的字符,将它们正确呈现在 HTML 中,我想将该行为复制到新网站中,这是一个不同但具有相同代码和php.ini 设置。
【问题讨论】:
-
不要使用用于 ISO 编码数据的
utf8_encode/utf8_decode。除了更改之外,代码完全相同吗?如果查询这两个DB,PHP交互前的数据是否相同? -
是的,使用 phpMyAdmin 的查询返回相同的数据。我尝试解码/编码只是为了看看是否会发生什么事情,没有真正的期望
-
MariaDB 10.0.32 比 5.6.39 稍旧,但就本问题而言,它们应该是“相同的”。