代码之家  ›  专栏  ›  技术社区  ›  Bard.Mus

迁移后的数据库字符集环境

  •  1
  • Bard.Mus  · 技术社区  · 1 月前

    我最近迁移了一个网站,遇到了一个与字符编码相关的问题。数据库配置为Latin-1,而Apache默认为UTF-8。

    这种不匹配导致与网站中帖子的标记系统相关的序列化函数中断(unserialize():在27个字节中的偏移量22处出错),因为它们依赖于直接数据库连接来检索标记关联。

    哪个环境变量可能负责?我自己也问过这个问题,因为在之前的EC2环境中,似乎有某种环境变量在管理这种通信,确保PHP和数据库之间的正确交互。然而,迁移后,这个机制丢失了,我无法确定它是在哪里配置的。

    我尝试了以下方法,但没有成功:

    Checking and changing php.ini, httpd.conf and charset.conf settings to latin1 (default was set to UTF-8).
    Converting the database to UTF-8.
    Adding a condition in a function in config.php to force the connection to use latin1 (this temporarily resolved the issue but doesn’t explain the root cause).
    

    以下是之前EC2实例的服务器详细信息,新实例基于apache7.3 docker:

    MySQL: Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1
    Apache: 2.4.6 (CentOS)
    PHP: 7.3.33 with Zend OPcache v7.3.33
    

    只需添加更多详细信息:

    数据库存储在同一台EC2服务器上,我通过localhost连接到它。关于PHP的执行,我认为它是通过服务器上的mod_PHP运行的。我使用mysql函数与数据库交互。

    有人知道在之前的设置中,哪个环境变量或配置文件可能负责确保字符集的兼容性吗?

    任何见解都将不胜感激!

    2 回复  |  直到 1 月前
        1
  •  0
  •   hakre    1 月前

    有人知道在之前的设置中,哪个[参数]可能负责确保字符集的兼容性吗?

    任何见解都将不胜感激!

    简而言之:许多参数都会影响这一点。

    但你可能想了解它的根源(以及如何解决这个问题)

    实际上,您可能需要重新进行迁移。在重新进行迁移之前(在心理上),您必须首先迁移序列化数据并修复受影响列的列类型。

    (或者:如果您的安装程序当前适用于解决方法,则无需重新进行迁移即可完成此操作。应用修复程序(见下文)后 必须 在没有变通方法和变通方法的情况下工作 应该 被移除。)

    如所述 Storing a serialized object in MySql database (Q&A) ,序列化数据必须 以字符编码存储在文本字段中 除了 BINARY,除非你设法在连接上保留它的二进制值。

    删除双重否定:PHP序列化数据 应该 存储在二进制列中。如果你不这样做,可能会出现你所描述的问题。

    • 识别受影响的列。
    • 测试 未序列化() 使用会引发您看到的错误的连接编码对已标识的列进行比较。
    • 通过将列的编码转换为二进制来更改列。
    • 测试 未序列化() 对于迁移的列,它现在应该不受 任何 连接编码。

    UTF-8现在错了吗?不,您在浏览器中使用UTF-8做得很好,这大大提高了书面文本、JSON文本和HTML/XML数据的可移植性和互操作性。

    五月 想考虑一下 之后 您成功地解决了序列化列从Latin-1迁移到UTF-8的问题,其他文本列也是如此。

    这将帮助您完全迁移数据库,并了解数据库字符集/连接编码以及所有这些配置细节。但我建议先练习BINARY列(PHP序列化数据)。


    参考

        2
  •  0
  •   Wiimm    1 月前

    这不是数据成员的字符集/排序规则的问题,而是数据如何传输的问题。您可以将客户端字符集设置为UTF-8:

    mydb = \mysqli_init();
    mydb->real_connect(...);
    mydb->set_charset('utf8mb4');  // <<< important
    

    使用此设置,数据库服务器(MySQL或MariaDB)将发送到PHP接口的所有数据编码为UTF-8。这允许您为数据库成员使用不同的字符集。