PHP 5.6 字符串乱码本质是UTF-8编码链断裂,需同步源文件(UTF-8无BOM)、HTTP响应头(header('Content-Type: text/html; charset=utf-8'))、表单accept-charset与default_charset、MySQL连接层(utf8mb4)及JSON输出标志(JSON_UNESCAPED_UNICODE)。

源文件与输出头必须同步为 UTF-8 无 BOM
这是最常见也最容易忽略的第一关。PHP 5.6 默认不读取 BOM,一旦文件开头有 BOM 字节(Windows 记事本常偷偷加),就会被当作普通字符输出,导致 header() 报 “headers already sent”,后续 charset 声明失效。
- 用 VS Code 或 Sublime Text 打开 PHP 文件,右下角确认编码显示为 UTF-8(不是 “UTF-8 with BOM”),然后执行 “Save with Encoding → UTF-8”
- 在所有
echo、print、HTML 输出前,第一行写:header('Content-Type: text/html; charset=utf-8'); - 检查有没有
require/include的文件——它们也必须是 UTF-8 无 BOM,且不能含空行或空格
$_POST 和表单提交中文要双向确认编码
浏览器按页面声明的编码发数据,PHP 按 default_charset 解析。两者不一致,$_POST['name'] 就是乱码。
- HTML 表单页顶部加:
<meta charset="utf-8">(放在<head>最前面) - 表单标签显式声明:
<form method="post" accept-charset="UTF-8"> - 确认 php.ini 中
default_charset = "UTF-8"(PHP 5.6 默认已是,但有些运维环境会覆盖) - 不要依赖
mb_internal_encoding()修正 $_POST —— 它只影响 mbstring 函数,不影响超全局变量解析
MySQL 查询中文乱码:光设 header 没用
网页能显示中文 ≠ 数据库读出来是中文。PHP 从 MySQL 拿数据时,连接层用的字符集才是关键。
- 使用 mysqli 时,在连接后立即执行:
$mysqli->set_charset('utf8mb4');(注意是 utf8mb4,不是 utf8) - 使用 PDO 时,在 DSN 中加入:
mysql:host=localhost;dbname=test;charset=utf8mb4 - 确保 MySQL 服务端配置了
character_set_server = utf8mb4,建库建表时也指定CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci - 避免用
SET NAMES utf8(它只临时生效,且 utf8 在 MySQL 中实际是 utf8mb3,不支持 emoji)
json_encode() 输出中文仍是 \uXXXX?加标志位
PHP 5.6 已支持 JSON_UNESCAPED_UNICODE,不用升级版本就能让中文原样输出。
立即学习“PHP免费学习笔记(深入)”;
- 正确写法:
echo json_encode($data, JSON_UNESCAPED_UNICODE); - 如果数据来源不可靠(比如用户粘贴、旧系统导出),先做一次清理:
$clean = mb_convert_encoding($raw, 'UTF-8', 'UTF-8');再 encode - 别忘了配合响应头:
header('Content-Type: application/json; charset=utf-8'); - 若前端仍乱码,请检查是否漏了 header,或 Nginx/Apache 配置覆盖了 PHP 的 Content-Type



















