PHP 5 升级到 PHP 7 后乱码的根本原因是 mysql_* 扩展被移除且默认字符集行为变化,需全程统一 utf8mb4 编码:替换函数为 mysqli 或 PDO、MySQL 服务端及表结构设为 utf8mb4、PHP 文件存为 UTF-8 无 BOM、输出头声明 charset=utf-8。

PHP 5 升级到 PHP 7 后出现乱码,根本原因不是“编码变了”,而是 mysql_* 扩展被彻底移除 + 默认字符集行为变化导致的连锁反应。修乱码不能只改 header() 或数据库连接编码,得从数据流全程对齐。
PHP 7 已彻底删除 mysql_connect(),必须换 mysqli 或 PDO
PHP 7.0 起,mysql_connect()、mysql_query() 等函数直接报 Fatal error: Uncaught Error: Call to undefined function mysql_connect()。这不是警告,是硬性报错,必须替换。
- 用
mysqli:改写连接为mysqli_connect($host, $user, $pass, $db, $port),并立刻调用mysqli_set_charset($conn, 'utf8mb4') - 用
PDO:DSN 中显式指定字符集,例如mysql:host=localhost;dbname=test;charset=utf8mb4,且创建时加选项[PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"] - 别用
mysql_* → mysqli_*的简单字符串替换——mysqli_query()第一个参数是连接资源,顺序和返回值逻辑都不同
SET NAMES utf8 在 PHP 7 + MySQL 5.5.3+ 下不够用
很多老代码靠 mysql_query("SET NAMES utf8") 撑过 PHP 5,但迁移到 PHP 7 后即使用了 mysqli,仍乱码,问题常出在字符集粒度上:utf8 是 MySQL 的阉割版(最多 3 字节),不支持 emoji 和部分生僻汉字;而 utf8mb4 才是真正的 UTF-8。
- MySQL 服务端配置需确认
character_set_server = utf8mb4,且对应库/表/字段的COLLATION是utf8mb4_unicode_ci或类似 - PHP 连接后必须执行
SET NAMES utf8mb4(或用mysqli_set_charset()),仅改php.ini的default_charset没用 - HTML 输出页仍要保留
header('Content-Type: text/html; charset=utf8mb4')或等效的(注意:浏览器只认utf-8,这里写utf8或utf-8都行,但后端必须用utf8mb4)
文件本身编码与 mb_internal_encoding() 不匹配会放大乱码
PHP 文件若存为 GBK 或 ANSI 编码,而脚本里又用了中文字符串(如 echo "用户";),PHP 7 默认按 UTF-8 解析源码,就会把双字节中文当两个非法字符处理,输出成 。
立即学习“PHP免费学习笔记(深入)”;
- 编辑器保存 PHP 文件时,务必选
UTF-8 无 BOM(BOM 会导致 headers already sent 错误) - 在脚本开头加
mb_internal_encoding('UTF-8'),确保mb_*函数(如mb_substr)行为一致 - 检查
php.ini中mbstring.internal_encoding是否设为UTF-8;PHP 7.2+ 已废弃该配置项,强制以 UTF-8 为准,旧配置反而可能引发警告
真正卡住人的地方,往往不是某一行代码没改对,而是 MySQL 表结构仍是 utf8 字符集、PHP 连接用了 utf8、但文件存成了 GBK —— 三者错位,乱码就变成“有时正常、有时异常”的玄学问题。逐层确认字符集来源比盲目加 iconv() 更可靠。











