thinkphp 8.0 中文乱码主因是环境编码不统一:入口文件须为utf-8无bom、public/index.php顶部显式设置header('content-type: text/html; charset=utf-8')、数据库dsn中必须指定charset=utf8mb4。

ThinkPHP 8.0 安装后中文乱码,基本不是框架本身的问题,而是环境层编码未对齐——尤其是 PHP 文件保存格式、HTTP 响应头、数据库连接三者中任一环节用了非 UTF-8(比如带 BOM 的 UTF-8、GBK 或 ANSI),就会立刻触发乱码。
PHP 文件保存为 UTF-8 without BOM
VS Code、PhpStorm 等编辑器默认可能用 UTF-8 with BOM 保存文件,而 thinkphp 入口文件(如 public/index.php)一旦开头含 BOM(\xEF\xBB\xBF),PHP 就会在输出任何内容前先输出这三个字节,导致 headers already sent 错误,进而让 header('Content-Type: text/html; charset=utf-8') 失效。
- 用 VS Code 打开
index.php,右下角查看编码显示,若为UTF-8 with BOM,点击切换 →Save with Encoding→ 选UTF-8(不含 BOM) - Linux 下可用
file -i public/index.php验证:输出应为charset=utf-8,且不含with bom - 切勿用 Windows 记事本另存为“UTF-8”,它默认加 BOM;改用 Notepad++ 或 VS Code
入口文件必须显式设置 header
ThinkPHP 8.0 不再自动注入 Content-Type 响应头,依赖开发者自行控制输出编码。即使 HTML 里写了 <meta charset="UTF-8">,浏览器仍可能按响应头判断解码方式,而默认响应头无 charset 时,多数浏览器 fallback 到 ISO-8859-1 或系统本地编码。
- 在
public/index.php最顶部(<?php后第一行,且前面**不能有任何空格、空行、BOM**)添加:header('Content-Type: text/html; charset=utf-8'); - 如果使用 CLI 或 API 模式(返回 JSON),则应改为:
header('Content-Type: application/json; charset=utf-8'); - 用
curl -I http://localhost检查响应头,确认返回中包含Content-Type: text/html; charset=utf-8
MySQL 连接必须指定 charset=utf8mb4
ThinkPHP 8.0 默认 PDO DSN 不带 charset 参数,即使数据库建表用的是 utf8mb4,PHP 连接时仍可能以 latin1 或 utf8(即 utf8mb3)握手,导致读出的中文变成 ??? 或乱码字节。
- 修改
config/database.php中的dsn,确保包含;charset=utf8mb4,例如:'dsn' => 'mysql:host=127.0.0.1;dbname=tp8;charset=utf8mb4' - 若用
hostname/database等字段拼接 DSN,请在params中显式加:PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4" - 检查 MySQL 服务端配置:确认
my.cnf中[mysqld]段有character-set-server = utf8mb4和collation-server = utf8mb4_unicode_ci
PDF 导出中文乱码需额外加载字体
若项目用 dompdf/dompdf 导出 PDF,即使网页正常,PDF 仍乱码——因为 dompdf 默认不支持中文字体,且不会自动加载系统字体。它只认自己 lib/fonts/ 目录下经 load_font.php 处理过的字体文件。
- 下载或生成一个支持中文的 TTF(如 Noto Sans CJK SC、simhei.ttf),放到项目根目录(与
vendor同级) - 运行
php load_font.php "Noto Sans CJK SC" noto-sans-sc.ttf(需先确保load_font.php已存在并可执行) - 导出前在代码中指定字体:
$pdf->set_option('defaultFont', 'Noto Sans CJK SC'); - 注意:
load_font.php必须用 UTF-8 without BOM 保存,否则执行时报错或生成字体失败
真正容易被忽略的是 BOM 和 DSN 中的 charset ——前者让 header 失效,后者让数据库读写失准,两者叠加,调试时现象相互干扰,反而让人反复怀疑是框架 bug 或模板问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











