根本原因是字符集链路断裂:phpMyAdmin导出依赖Language选项(须选“中文-chinese simplified”而非-gb2312)、Character set of the file手动设为utf8mb4、MySQL服务端character_set_server为utf8mb4、phpMyAdmin配置中charset与connection_charset均为utf8mb4,且SQL文件必须为UTF-8无BOM编码。

phpMyAdmin 导出 SQL 查询结果时中文变问号或方块,根本原因不是“导出功能坏了”,而是它默认按当前连接的字符集编码写入文件,而这个连接层编码往往没对齐 UTF-8(更准确说是 utf8mb4)。
导出前没选对 Language 和字符集选项
phpMyAdmin 的导出行为严重依赖右上角的 Language 下拉菜单和下方的 Character set of the file 设置。这两个地方不一致,导出文件就大概率带乱码。
-
Language选 “中文-chinese simplified-gb2312” → 导出文件实际是 GBK 编码,但文件头无声明,多数编辑器会误判为 UTF-8,打开即乱码 -
Language选 “中文-chinese simplified”(注意末尾没-gb2312)→ 导出为 UTF-8 无 BOM,这才是安全选择 -
Character set of the file必须手动选utf8mb4,不能留空或选auto;否则即使 Language 对了,导出内容仍可能被当 latin1 处理
MySQL 连接层字符集没设成 utf8mb4
phpMyAdmin 在导出前会执行 SET NAMES utf8(老版本)或 SET NAMES utf8mb4(新版本),但这取决于它的配置和 MySQL 服务端是否支持。如果服务端 character_set_server 是 latin1,或者 phpMyAdmin 配置里没强制指定连接字符集,那导出的字符串字面量(比如 '张三')就会被按 latin1 解析再转存,结果就是乱码。
- 检查 MySQL 服务端:运行
SHOW VARIABLES LIKE 'character_set_server';,必须是utf8mb4 - 检查 phpMyAdmin 配置:在
config.inc.php中确认有$cfg['Servers'][$i]['charset'] = 'utf8mb4';和$cfg['Servers'][$i]['connection_charset'] = 'utf8mb4'; - PHP 层也要同步:
default_charset在php.ini中设为UTF-8(注意连字符)
SQL 文件被编辑器悄悄加了 BOM 头
你用记事本、Sublime 或某些 VS Code 版本另存为 “UTF-8”,其实默认保存的是 UTF-8 with BOM。MySQL 客户端(包括 phpMyAdmin 后端解析逻辑)看到开头的 EF BB BF 字节,会把它当非法字符跳过或截断,导致后续的 INSERT 语句错位,中文字段值被吃掉一部分。
立即学习“PHP免费学习笔记(深入)”;
- 验证方法:
hexdump -C your_export.sql | head -n 1,看到ef bb bf就确诊 - Linux/macOS 清除 BOM:
sed -i '1s/^\xEF\xBB\xBF//' your_export.sql - Windows 下用 VS Code:右下角点编码名 → “Save with Encoding” → 选
UTF-8(明确不含 BOM)
导出内容本身来自 latin1 编码的表
如果原表建的时候用的是 CHARACTER SET latin1,而里面存的中文其实是用 GBK 或 UTF-8 编码硬塞进去的(常见于历史遗留库),那 phpMyAdmin 导出时会忠实地按 latin1 解码再写入 SQL 文件——结果就是一堆 ????。
- 先查字段真实内容:
SELECT HEX(column_name) FROM table_name LIMIT 1;,如果返回类似E4B8ADE69687(UTF-8 编码的“中文”),说明数据本身是 UTF-8,只是表声明错了 - 修复方式不是
CONVERT TO,而是改列定义:ALTER TABLE t MODIFY c VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 别直接
ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4,那会二次转码,把已损坏的数据彻底搞废
最易被忽略的一点:phpMyAdmin 导出时不会主动帮你补全 SET NAMES utf8mb4 到文件开头,也不会在每条 INSERT 前加字符集提示。它完全信任连接层的状态。所以一旦连接层崩了,导出即废——哪怕你在界面上看到预览是正常的。



















