PHP中文乱码需五处统一为UTF-8无BOM:PHP文件保存、header响应头、HTML meta声明、MySQL连接与表字段、Web服务器配置,缺一不可。

PHP中文乱码不是单一环节出错,而是编码链路上多个节点不一致导致的连锁反应。根治的关键在于从文件保存、脚本输出、页面声明、数据库交互到服务器配置,全程统一为 UTF-8(严格要求无 BOM),且各环节彼此验证、互不抵消。
PHP源文件必须是UTF-8无BOM
编辑器默认保存格式常为系统本地编码(如 Windows 的 ANSI/GBK),直接写入中文后,PHP 解析器会按错误字节流读取,造成开头隐式输出、headers already sent 等问题。
- 用 VS Code / Notepad++ / Sublime 打开 PHP 文件,右下角确认编码显示为“UTF-8”且不含“with BOM”字样
- 若显示 GBK、ANSI 或 UTF-8 with BOM,选择“另存为” → 明确选“UTF-8(无 BOM)” → 覆盖原文件
- Linux 下可用命令验证:
file -i your_script.php,输出应为charset=utf-8且不含with bom
PHP脚本开头强制声明输出编码
仅靠 HTML meta 不可靠,浏览器优先信任 HTTP 响应头。header() 必须在任何输出(含空格、换行、echo)之前执行,否则失效。
- 在 PHP 文件最顶部(
<?php后立即写,前面不能有任何字符)添加:header('Content-Type: text/html; charset=utf-8'); - 如需兼容旧版或调试,可用
curl -I http://yoursite/test.php检查响应头是否含Content-Type: text/html; charset=utf-8 - 若启用输出缓冲,可加
ob_start();在 header() 前,避免意外前置输出
HTML页面内嵌meta与结构位置要规范
meta 标签是后备机制,但必须放在 最靠前位置(在 <title></title> 和外部资源引入之前),否则部分浏览器可能忽略。
立即学习“PHP免费学习笔记(深入)”;
- 写法唯一推荐:
<meta charset="UTF-8">(注意大小写不敏感,但建议大写 U、T、F、8) - 禁止使用旧式写法如
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">,易与 header 冲突 - 确保该标签位于
内,且是前几行代码之一,不要被 PHP 注释或空行隔开
数据库连接与字段编码必须用 utf8mb4
MySQL 的 utf8 实际只支持最多 3 字节 Unicode(不含 emoji 和部分生僻汉字),真正全量 UTF-8 是 utf8mb4。表、字段、连接三者缺一不可。
- 建表时指定:
CREATE TABLE ... DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; - mysqli 连接后立即执行:
mysqli_set_charset($conn, 'utf8mb4'); - PDO 连接 DSN 中加入:
mysql:host=localhost;dbname=test;charset=utf8mb4,并设置选项PDO::ATTR_EMULATE_PREPARES => false - 验证方式:
SHOW CREATE TABLE your_table;查看字符集是否为utf8mb4
Web服务器与PHP运行环境需兜底
当以上都正确仍乱码,可能是服务器层默认编码覆盖了 PHP 设置,或 mbstring 扩展未启用导致函数行为异常。
- Apache:在
.htaccess或虚拟主机配置中加AddDefaultCharset UTF-8 - Nginx:在 server 或 location 块中加
charset utf-8; - PHP 配置检查:
phpinfo()中确认mbstring已启用,并设mb_internal_encoding('UTF-8');(尤其用于 mb_* 函数) - 禁用过时特性:
ini_set('magic_quotes_gpc', 0);(PHP



















