PHP中文乱码本质是字符集不统一,需MySQL连接、PHP文件编码、HTTP响应头、HTML meta四层均设为UTF-8;尤其要确保PHP文件无BOM、MySQL连接显式指定charset=utf8mb4、header与meta同步声明UTF-8。

PHP 中文乱码本质是字符集不统一,不是“加个 header 就能好”,关键在 MySQL 连接、PHP 文件保存、HTTP 响应、HTML 声明这四层必须一致用 UTF-8。
确认 PHP 文件本身是 UTF-8 无 BOM 编码
很多乱码根源其实在编辑器里——PHP 文件被存成了 GBK 或 UTF-8 with BOM。BOM 会提前输出不可见字符,导致 header() 失效、JSON 解析失败、session 启动报错。
- 用 VS Code / Sublime / Notepad++ 打开 PHP 文件,右下角检查编码显示为
UTF-8(不是UTF-8 with BOM) - VS Code:右键状态栏编码 → “Save with Encoding” → 选
UTF-8 - Notepad++:菜单栏“编码”→“转为 UTF-8 编码”(不是“UTF-8-BOM”)
- Linux 下可用
file -i your.php检查,输出含charset=utf-8才算对
MySQL 连接层必须显式设 charset
即使数据库、表、字段都是 utf8mb4,PHP 默认连接仍可能走 latin1。PDO 和 mysqli 行为不同,不能只靠建表语句。
- PDO 连接时必须在 DSN 加
;charset=utf8mb4:$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8mb4', $user, $pass); - mysqli 推荐用
set_charset('utf8mb4')(不是query("SET NAMES utf8")):$mysqli->set_charset('utf8mb4'); - 避免用
mysql_query("SET NAMES utf8")—— 已废弃且不支持 4 字节 emoji
HTTP 响应头与 HTML meta 必须同步声明
Content-Type 响应头和 <meta charset> 不一致时,浏览器会按自己的逻辑猜编码,中文就容易崩。
立即学习“PHP免费学习笔记(深入)”;
- PHP 输出前加:
header('Content-Type: text/html; charset=utf-8'); - HTML 的
<head>内第一行必须是:<meta charset="UTF-8">
(注意大小写不敏感,但别写成utf-8小写——部分旧浏览器有兼容问题) - 如果用了模板引擎(如 Twig、Blade),确保它没在你之前输出内容,否则
header()会报headers already sent
POST 表单提交中文乱码?检查 enctype 和 Accept-Charset
普通 application/x-www-form-urlencoded 表单,只要页面是 UTF-8,PHP 就能正常接收中文;但上传文件或特殊 enctype 容易出问题。
- 表单无需加
accept-charset="UTF-8"(现代浏览器默认跟随页面编码),加了反而可能干扰 - 上传文件时,
$_FILES['xxx']['name']在 Windows + Apache 下可能为 GBK 编码,需用mb_convert_encoding()转:$filename = mb_convert_encoding($_FILES['file']['name'], 'UTF-8', 'GBK');
- 用
var_dump($_POST)直接看原始值,如果已经是乱码,说明前端没发对;如果是问号(?)或空,大概率是 MySQL 插入时没设 charset
最常被忽略的是:数据库连接 charset 和 PHP 文件编码这两个点,改完一个不等于全通。建议按顺序逐层验证——先看 var_dump 输出是否正常,再查数据库存进去是不是乱码,最后看浏览器渲染有没有问号。中间任何一层断掉,都会让中文变成“?”或方块。



















