如何使用PHP PDO向MySQL正确插入韩文等非英文字符
问题原因
- 你在DSN中指定的charset未生效:PHP PDO默认开启模拟预处理功能,该模式下会忽略DSN中设置的字符集参数,使用MySQL服务端默认的字符集处理字符串,导致韩文字符转码错误变成问号。
- MySQL自带的
utf8字符集为阉割版本(实际是utf8mb3),仅支持最多3字节的Unicode字符,虽然理论上支持韩文,但存在兼容性隐患,同时如果数据库、客户端的字符集未统一也会导致显示乱码。 - 你用于查看数据库内容的客户端(命令行、可视化工具等)默认字符集和数据表字符集不匹配,哪怕实际存储正确,查询时也会显示为问号。
- PHP源码文件本身编码不是UTF-8无BOM格式,代码中写死的韩文字符本身就是乱码,插入数据库后自然显示异常。
解决方案
- 统一替换字符集为utf8mb4,兼容所有Unicode字符,避免后续兼容性问题:
- 修改数据库默认字符集:
ALTER DATABASE mydb_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- 修改已有数据表的字符集:
ALTER TABLE base_tab CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;- 新创建库表时直接指定字符集为utf8mb4即可。
- 修改PDO初始化代码,关闭模拟预处理,明确字符集设置:
$db = new PDO ('mysql:host=localhost;dbname=mydb_test;charset=utf8mb4', 'root', // 用户名 ''// 密码 ); // 关闭模拟预处理,强制使用MySQL原生预处理,避免字符集设置失效 $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); // 可选:开启异常模式方便后续排查SQL错误 $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - 调整数据库查看客户端的字符集设置:
- 命令行查询前先执行
SET NAMES utf8mb4;再执行查询语句查看内容。 - 可视化工具(如Navicat、DBeaver等)在连接配置中把编码设置为
utf8mb4,不要使用默认自动识别选项。
- 命令行查询前先执行
- 确认保存PHP代码的文件编码为UTF-8无BOM格式,可在代码编辑器的编码设置中查看调整。
- (可选一劳永逸配置)修改MySQL配置文件:
Linux下修改my.cnf、Windows下修改my.ini,添加如下配置后重启MySQL服务:[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4
内容的提问来源于stack exchange,提问作者Nancy Moore
相关产品推荐
相关产品推荐

