ThinkPHP 乱码主因是数据库连接未设 charset=utf8mb4 和文件含 BOM;TP5/6 已弃用 default_charset 配置,需确保 database.php 中 charset 为 utf8mb4、DSN 一致、MySQL 服务端字符集匹配,并所有 PHP/模板文件保存为 UTF-8 without BOM。

ThinkPHP 默认就是 UTF-8,但实际运行中乱码,问题几乎全出在配置没对齐或被覆盖。
确认 default_charset 配置是否生效
ThinkPHP 5.1+ 已移除全局 default_charset 配置项,它只在早期版本(如 3.2)的 Conf/config.php 中起作用。现在真正控制 HTTP 响应头字符集的是 default_return_type 和模板输出逻辑。
- TP6 默认使用
json或html作为default_return_type,而html类型会自动加Content-Type: text/html; charset=utf-8 - 如果你手动调用
header()或用了第三方输出,这个头可能被覆盖——检查控制器里有没有写header('Content-Type: text/html; charset=gbk');这类代码 - 在
config/app.php中设置'default_charset' => 'utf-8'是无效的,该配置项已废弃,写了也不报错,但完全不生效
数据库连接层必须显式指定 charset
即使 PHP 文件、HTTP 头、模板都是 UTF-8,只要数据库连接没设对,SELECT 出来的中文照样是乱码。
- TP5/6 的数据库配置在
config/database.php,关键字段是'charset' => 'utf8mb4'(不是utf8) - MySQL 用
utf8实际只支持 3 字节字符,emoji 和部分生僻字会截断;utf8mb4才是完整 UTF-8 - 如果用 PDO,还需确保
'dsn' => 'mysql:host=...;charset=utf8mb4'与配置项一致,二者冲突时以 DSN 中的为准 - 执行
SHOW VARIABLES LIKE 'character_set%';确认 MySQL 服务端也是utf8mb4,否则光改 PHP 没用
模板文件和 PHP 源码本身得是 UTF-8 无 BOM
编辑器保存格式不对,会导致整个页面头部多出不可见字符,进而破坏 header() 发送或 JSON 输出。
立即学习“PHP免费学习笔记(深入)”;
- 所有
.php控制器、模型、配置文件,以及.html或.php模板,必须存为UTF-8 without BOM - Sublime / VS Code 默认保存就是无 BOM,但老版 Notepad++ 或某些国产编辑器默认带 BOM,一保存就埋雷
- 用命令行检查:
file -i your_file.php显示charset=utf-8即可;若显示charset=utf-8-bom,说明有 BOM,需另存为无 BOM 格式 - TP6 的
view_replace_str如果替换内容含中文,且源文件带 BOM,也可能导致输出错位
最常被忽略的是数据库连接层的 charset 和文件编码 BOM 问题——HTTP 头看着对,但数据进来就乱,或者页面开头空白、JSON 解析失败,八成是这两个地方没扫干净。



















