必须修改phpEnv中mysql\my.ini的[mysqld]段,添加character-set-server=utf8mb4等三行并重启MySQL服务,否则character_set_server默认为latin1;再依次修正数据库、表、字段字符集,并在PHP连接后立即执行set_charset('utf8mb4')或exec("SET NAMES utf8mb4"),同时确保HTML和HTTP响应头均为UTF-8。

phpEnv 里 MySQL 启动后仍显示 latin1?先看 character_set_server
phpEnv 是 Windows 下的集成环境,它默认启动的 MySQL 实际上可能沿用旧版配置(比如 my.ini 中未显式设置字符集),导致 character_set_server 仍是 latin1。这不是 phpEnv “坏了”,而是它的 MySQL 配置文件没被正确覆盖。
进 phpEnv 安装目录,找到 mysql\my.ini(不是 mysql\bin\my.ini,也不是临时生成的 conf),在 [mysqld] 段下确认有这三行:
[mysqld] character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci skip-character-set-client-handshake = ON
删掉任何形如 default-character-set = utf8 或 init-connect='SET NAMES utf8' 的过时写法——它们不兼容 utf8mb4,且 init-connect 对 SUPER 用户无效,反而掩盖问题。
改完必须重启 phpEnv 的 MySQL 服务(不是只点“重启 Apache”),否则配置不加载。
立即学习“PHP免费学习笔记(深入)”;
phpEnv 环境下 PHP 连接 MySQL 时乱码?别只信 DSN 里的 charset=utf8mb4
Windows 下 phpEnv 使用的 PHP 版本常带较老的 MySQLi/PDO 驱动,某些版本会忽略 DSN 中的 charset 参数,尤其当连接复用(如 PDO 持久连接)或使用了封装类时。
安全做法是:连接建立后,**立刻执行字符集声明**:
- mysqli 风格:
$mysqli->set_charset('utf8mb4')(比mysqli_query($mysqli, "SET NAMES utf8mb4")更底层、更可靠) - PDO 风格:
$pdo->exec("SET NAMES utf8mb4")(即使 DSN 已含charset=utf8mb4,也补这一句)
验证是否生效,可在连接后加一行:var_dump($mysqli->get_charset()) 或 var_dump($pdo->getAttribute(PDO::ATTR_CLIENT_VERSION)),确认输出中包含 utf8mb4。
表和字段还是乱码?phpEnv 不自动升级旧表结构
phpEnv 重装或迁移数据库时,只复制 .frm 和 .ibd 文件,不会重建表定义。哪怕你已把 my.ini 改对、PHP 连接设好,老表的 CHARACTER SET 仍可能是 utf8 或 latin1。
逐级修正,顺序不能错:
- 查库:
SELECT DEFAULT_CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'your_db'; - 查表:
SHOW CREATE TABLE your_table;(重点看末尾DEFAULT CHARSET=...) - 查字段:
SELECT COLUMN_NAME, CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'your_db' AND DATA_TYPE IN ('varchar','text');
执行 ALTER 时注意:
- 仅改库默认值:
ALTER DATABASE your_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 重编码整张表(含数据转换):
ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(大表慎用,会锁表) - 只改列定义(不触碰数据):
ALTER TABLE your_table MODIFY COLUMN name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
phpEnv 自带 phpMyAdmin 显示正常,但 PHP 脚本输出问号?通信层没对齐
这是最典型的“假正常”:phpMyAdmin 内部自动发了 SET NAMES utf8mb4,而你的 PHP 脚本没发,所以连的是同一台 MySQL,表现却不同。
检查点很具体:
- PHP 脚本里有没有在
new mysqli()或new PDO()之后,**紧跟着**调用字符集设置?漏掉就等于用服务器默认(latin1)解码utf8mb4数据 - HTTP 响应头是否被覆盖?比如用了框架或中间件,
header("Content-Type: text/html; charset=gbk")会强制浏览器用 GBK 解析 UTF-8 字节流 - HTML 页面里
<meta charset="utf-8">写对了没?注意不是utf8(少个mb4),也不是UTF-8大写(部分旧浏览器敏感)
真正起作用的是三者闭环:MySQL 服务端用 utf8mb4 存 → 连接层用 utf8mb4 传 → PHP 输出用 utf8mb4 编码发给浏览器。缺一环,中文就断在半路。



















