必须将 charset 全链路统一为 utf8mb4:ci4 配置中设 'charset' => 'utf8mb4',mysql 服务端需在 my.cnf 中配置 character_set_server=utf8mb4,数据库、表、字段均须显式转为 utf8mb4 编码,否则中文存储仍会乱码。

直接把 charset 改成 utf8mb4,并确保整个链路(连接、表、字段)都对齐。latin1 本身就不支持中文,设成它等于主动放弃中文存储能力。
CodeIgniter4 配置必须改 charset
在 app/Config/Database.php 中,找到数据库配置数组,将 'charset' 明确设为 'utf8mb4':
'collation' => 'utf8mb4_unicode_ci',
仅改这个还不够——CI4 的 PDO 连接会用它拼出 charset=utf8mb4 参数,但若 MySQL 服务端或表结构不匹配,仍会乱码。
MySQL 服务端三件套要一致
连上 MySQL 执行:
SHOW VARIABLES LIKE 'character_set_client';SHOW VARIABLES LIKE 'character_set_connection';
SHOW VARIABLES LIKE 'character_set_results';
这三项必须全是 utf8mb4。如果其中一个是 latin1,即使 CI4 配了 utf8mb4,插入时也会被中间层转成问号。
临时验证可执行:SET NAMES utf8mb4;
但这是会话级,重启连接就失效。长期方案是:在 my.cnf 的 [mysqld] 段加:
collation_server = utf8mb4_unicode_ci
然后重启 MySQL(systemctl restart mysqld)。
已有数据库和表要显式转 utf8mb4
CI4 配置改了,但老表如果建的时候没指定字符集,大概率继承的是 latin1 数据库,默认用 latin1 存中文。
先查库默认字符集:SHOW CREATE DATABASE your_db_name;
再查表:SHOW CREATE TABLE your_table_name;
如果看到 CHARSET=latin1 或 CHARSET=utf8(注意不是 utf8mb4),就得改:
-
改库:
ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci; -
改表:
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:大表执行 CONVERT TO 会锁表,建议在低峰期操作。
别漏掉字段级声明(尤其 TEXT 类型)
有些字段即使表整体转了 utf8mb4,也可能因建表时显式指定了 CHARACTER SET latin1 而保持旧编码。
检查字段编码:SHOW FULL COLUMNS FROM your_table_name;
看 Collation 列是否为 utf8mb4_unicode_ci。
单独改字段(例如一个 content TEXT 字段):ALTER TABLE your_table_name MODIFY content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
utf8mb4 是唯一能完整支持中文、emoji 和生僻字的 MySQL 字符集,MySQL 的 utf8 实际是 utf8mb3,早已该淘汰。











