根本原因是phpmyadmin导出时依据顶部language选项自动插入set names命令,而非数据库实际编码;选chinese simplified (zh-utf-8)才生成set names utf8mb4,否则如选english会强制用latin1导致乱码。
根本原因不是文件保存编码错了,而是 phpmyadmin 在导出前悄悄发了一条 set names latin1(或 gb2312)——它按这个字符集去读数据库里的中文,再原样写进 sql 文件,结果就变成乱码字节。
导出时语言设置直接决定 SET NAMES 命令内容
phpMyAdmin 不是“根据数据库实际编码”来导出,而是根据你顶部菜单选的 Language 选项,自动推导并插入 SET NAMES。比如:
- 选
Chinese simplified (zh-gb2312)→ 导出开头是SET NAMES gb2312 - 选
Chinese simplified (zh-utf-8)→ 导出开头是SET NAMES utf8mb4(注意:不是utf8) - 选
English(默认)→ 导出开头是SET NAMES latin1,哪怕你数据库全是utf8mb4,也会乱码
这个 SET NAMES 是导出逻辑的“解码指令”,它告诉 MySQL:“请用这个字符集把字段值转成字节再给我”。一旦错配,SELECT HEX(name) 看到的是正确 UTF-8 字节,但导出文件里写的却是被当成 latin1 解出来的乱码字节。
“自定义导出”里那个 Export character set 下拉框是摆设
很多用户以为在导出页勾选了 utf8mb4 就万事大吉,其实它只影响注释和部分元数据,**不改变 SET NAMES 的值,也不改变 INSERT 语句中字符串字面量的编码方式**。真正起作用的只有语言选择。
- 必须先选对
Language,再点“自定义”,否则下拉框选什么都无效 - 如果没看到
zh-utf-8,说明 phpMyAdmin 版本太旧或语言包被裁剪,要去phpEnv\phpmyadmin\libraries\database_interface.lib.php第 168 行附近注释掉过滤-utf-8后缀的if判断 - 导出后用
head -n 5 your.sql确认第一行是不是SET NAMES utf8mb4,不是就白改
MySQL 服务端默认字符集不匹配会放大问题
即使你语言选对了,如果 MySQL 的 character_set_server 是 latin1,phpMyAdmin 在连接初始化时可能 fallback 到 latin1,导致后续所有操作(包括导出读取)都走错通道。
- 执行
SHOW VARIABLES LIKE 'character_set_server';,如果不是utf8mb4,需在my.cnf的[mysqld]段加:character-set-server = utf8mb4 - 改完必须重启 MySQL,仅 reload 配置不生效
- phpMyAdmin 的
config.inc.php中也要同步设$cfg['Servers'][$i]['charset'] = 'utf8mb4';,否则连接层仍可能降级
导出文件带 BOM 或编辑器二次转码会让乱码“坐实”
即使 SET NAMES utf8mb4 正确、MySQL 也支持,导出文件若被记事本或某些编辑器存成 UTF-8 with BOM,导入时 MySQL 客户端(尤其是命令行)会把 BOM(EF BB BF)当非法字符,导致后续建表语句解析偏移,中文字段值被截断或错位。
- 用
hexdump -C your.sql | head -n 1查前 3 字节,看到ef bb bf就要删 - VS Code 打开 → 右下角点编码名 → “Save with Encoding” → 选
UTF-8(明确不含 BOM) - 别信“另存为 UTF-8”,很多编辑器默认仍带 BOM;Windows 记事本尤其危险,尽量不用
最易被忽略的一点:导出时语言选对了,但导出后用错误编码打开再保存,等于亲手把已正确的文件二次损坏。确认乱码是否真出自导出环节,先用 file -i your.sql(Linux/macOS)或 VS Code 编码识别功能看真实编码,再动手改。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











