网站迁移后字符编码不兼容:寻找PHP与数据库适配的环境变量
核心原因
你遇到的unserialize(): Error at offset...报错,本质是序列化字符串的字节长度与实际读取的字节数不匹配:数据库存储的是Latin1编码的序列化数据,当PHP用UTF-8连接数据库时,会把Latin1字节误当作UTF-8解析,导致部分字符的字节数被改变(比如Latin1的单字节字符在UTF-8下可能被错误解析为多字节),破坏了序列化字符串的长度标记,最终触发反序列化错误。
你尝试将数据库转换为UTF-8未解决问题,是因为原有的序列化数据是基于Latin1编码生成的,转换数据库编码时会改变这些数据的字节结构,进一步破坏序列化字符串的长度信息,所以反序列化依然报错。
原EC2环境可能的配置项
结合你使用的PHP mysql扩展、CentOS环境,原环境大概率是通过以下配置自动统一了PHP与MySQL的字符集:
1. PHP配置文件(php.ini)的mysql.default_charset参数
原EC2的php.ini中可能设置了:
mysql.default_charset = latin1
这个参数会让PHP的mysql扩展在建立数据库连接时,自动将连接字符集设为latin1,无需在代码中手动调用mysql_set_charset()。迁移后的Docker环境如果未配置该参数,PHP会默认使用UTF-8连接,导致编码不匹配。
2. MySQL配置文件(my.cnf/my.ini)的客户端字符集
原EC2的MySQL(MariaDB)配置文件(通常在/etc/my.cnf或/etc/mysql/my.cnf)的[client]段可能有:
[client] default-character-set = latin1
这个配置会让所有通过客户端连接MySQL的程序(包括PHP的mysql扩展)默认使用latin1字符集,覆盖PHP端的默认设置。
3. Apache的局部字符集配置
原环境可能在网站根目录的.htaccess文件,或者Apache虚拟主机配置中,设置了:
AddDefaultCharset ISO-8859-1
ISO-8859-1是Latin1的别名,这个配置会强制Apache响应内容使用Latin1编码,确保页面输出与数据库编码一致,避免前端编码转换干扰。
验证与修复建议
- 检查原EC2的
php.ini,确认mysql.default_charset的值; - 查看原EC2的MySQL配置文件,检查
[client]段的字符集设置; - 检查原网站根目录的
.htaccess文件,是否有字符集相关配置; - 在Docker环境中对应配置这些参数,即可替代代码中手动设置字符集的临时方案。
内容的提问来源于stack exchange,提问作者Bard.Mus

