MySQL数据库迁移PHP的UTF-8问题

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (82)

我正在将我现有的数据库迁移到另一台服务器。为了实现这一点,我使用phpMyAdmin SQL查询导出和导入数据库。一切正常,但网站上出现了一些UTF-8字符。我使用相同的PHP代码(在不同的服务器上但使用相同的PHP扩展和版本)获取它们。

我在新网站和数据库(旧的和新的)上看到的字符串示例(使用phpMyAdmin): péri-prothétique

我在旧网站上看到的字符串示例 péri-prothétique

正如您所看到的,PHP曾经以正确的方式自动编码字符,甚至认为字符在数据库中被破坏了,但是不再这样做了(即使我明确地utf8_encodeutf8_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: 由于这个问题,我弄清楚为什么我的条目被破坏了:双重编码是因为数据库整理是latin1_swedish_ci在表格整理时utf8_general_ci(遗留代码,如图)。这不能回答这个问题,因为旧网站自动“翻译”那些受损的字符,在HTML中正确呈现它们,我想将这种行为复制到新网站中,这是一个不同的网站,但具有相同的代码和php.ini设置。

提问于
用户回答回答于

要检查双重编码,请使用SELECT HEX(col)... é应该返回C3A9(正确的utf8),而是显示C383C2A9(双重编码)。

请参阅:UTF-8字符问题; 我看到的不是我存储的东西

如果您确实已确定您具有双重编码,则修复涉及

UPDATE tbl SET col = CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4);

请参阅http://mysql.rjweb.org/doc.php/charcoll#fixes_for_various_cases

是的,“双重编码”是一个无声的错误 - 两个错误是正确的(有点)。

用户回答回答于

我认为你应该检查你的MariaDB配置。

首先检查你的PHP代码,以了解是否没有误导性错字(但我认为它没有)

其次,检查您的MariaDB数据库/表结构[ 从这里提取 ]:

SELECT * FROM INFORMATION_SCHEMA.SCHEMATA;

三,检查你的MariaDB文件配置(my.cnf)[ 从这里提取 ]:

    [client]
default-character-set = utf8mb4

[mysqld]
character-set-server = utf8mb4

然后重启服务器:

mysql.server restart

希望它能帮助你解决问题。

再见

扫码关注云+社区

领取腾讯云代金券