MySQL连接字符集设置无效:PHP脚本无法修改会话连接字符集
解决PHP PDO无法修改MySQL连接字符集的问题
我来帮你排查这个问题——这种情况我碰到过好几次,大概率是PDO连接时的字符集设置方式不对,或者有隐藏的配置在干扰。咱们一步步来梳理:
1. 优先在PDO DSN中直接指定字符集
这是最可靠的方式,比手动执行SET NAMES更稳妥,因为PDO会自动同步character_set_client、character_set_connection和character_set_results这三个关键变量,还会处理校对规则的匹配。
正确的DSN写法应该是这样:
$pdo = new \PDO( "mysql:host=localhost;dbname=your_database;charset=utf8mb4", "your_username", "your_password", [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION // 开启异常模式,方便排查错误 ] );
注意:PHP 5.3.6之前的版本不支持在DSN里加charset参数,如果你用的是旧版本,就得用下面的方法。
2. 手动执行会话字符集设置(针对旧版本PHP)
如果你的PHP版本低于5.3.6,或者DSN设置后还是不生效,那就连接成功后立即执行字符集设置语句,并且要确保执行成功:
$pdo = new \PDO("mysql:host=localhost;dbname=your_database", "user", "pass"); // 执行字符集设置,用exec或者prepare都可以 $success = $pdo->exec("SET NAMES utf8mb4"); // 或者更严谨的写法,分别设置三个变量 $pdo->exec("SET character_set_client = utf8mb4"); $pdo->exec("SET character_set_connection = utf8mb4"); $pdo->exec("SET character_set_results = utf8mb4"); // 可以验证下是否生效 $stmt = $pdo->query("SHOW VARIABLES LIKE 'character_set_connection'"); $result = $stmt->fetch(PDO::FETCH_ASSOC); echo $result['Value']; // 应该输出utf8mb4
3. 排查隐藏的配置干扰
如果上面两种方法都没用,那可能是MySQL的全局配置在搞鬼:
- 检查my.ini里的
init_connect参数,如果设置了init_connect='SET NAMES latin1',这个语句会在每次非超级用户连接时自动执行,覆盖你设置的字符集。解决方法要么删掉这个配置,要么用超级用户(root)连接(但不推荐生产环境这么做)。 - 确认你的数据库和表的字符集是utf8mb4吗?虽然会话字符集是utf8mb4,但如果表本身是latin1,写入数据还是会有问题,但这和你说的“连接字符集没改变”不是一回事,不过也可以顺便检查下。
4. 验证会话字符集
不管用哪种方法,都要验证当前会话的字符集变量,执行以下查询:
SHOW VARIABLES LIKE 'character_set%'; SHOW VARIABLES LIKE 'collation%';
重点看character_set_client、character_set_connection、character_set_results这三个变量的值,应该都是utf8mb4才对。
内容的提问来源于stack exchange,提问作者user2180613
相关产品推荐
相关产品推荐

