在 CentOS + LAMP(Linux + Apache + MySQL + PHP) 环境中出现乱码,通常不是单一原因,而是 字符集(编码)在多个环节不一致 造成的。下面按常见原因 → 排查位置 → 解决方法给你系统梳理一下。
一、最常见原因总览
乱码本质是:
数据写入时编码 ≠ 数据读取时编码 ≠ 页面展示编码
常见环节:
- 文件本身编码
- Apache 响应头编码
- PHP 内部编码
- MySQL 数据库 / 表 / 连接编码
- 浏览器解析编码
二、逐项排查与解决
1️⃣ PHP 文件本身编码(最容易忽略)
✅ 推荐:UTF-8 无 BOM
❌ 错误示例:
- GBK
- UTF-8 带 BOM(会导致 header 已发送、乱码)
解决:
file -i index.php
应为:
index.php: text/x-php; charset=utf-8
编辑工具(vim / VS Code)统一保存为 UTF-8 无 BOM
2️⃣ Apache 未指定字符集
检查 Apache 配置
grep -R "AddDefaultCharset" /etc/httpd/
解决(推荐)
在 Apache 配置或 .htaccess 中加:
AddDefaultCharset UTF-8
或虚拟主机中:
<VirtualHost *:80>
DocumentRoot /var/www/html
AddDefaultCharset UTF-8
重启:
systemctl restart httpd
3️⃣ PHP 未设置编码
PHP 文件开头加:
header("Content-Type:text/html; charset=utf-8");
php.ini(可选)
default_charset = "UTF-8"
4️⃣ MySQL 字符集不一致(重灾区)
1️⃣ 查看 MySQL 编码
SHOW VARIABLES LIKE 'character_set%';
常见错误:
character_set_server = latin1
2️⃣ 修改 MySQL 配置(CentOS)
编辑:
vi /etc/my.cnf
添加:
[client]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
重启:
systemctl restart mysqld
3️⃣ 数据库 / 表 / 字段
ALTER DATABASE dbname CHARACTER SET utf8mb4;
ALTER TABLE tablename CONVERT TO CHARACTER SET utf8mb4;
5️⃣ PHP 连接 MySQL 未指定编码(极易乱码)
MySQLi
$mysqli->set_charset("utf8mb4");
PDO
new PDO(
"mysql:host=localhost;dbname=test;charset=utf8mb4",
$user, $pass
);
❌ 错误:
mysql_query("SET NAMES utf8"); // 老写法不稳定
6️⃣ 浏览器识别错误
确保:
- HTTP 响应头有
charset=utf-8 - HTML 中有:
<meta charset="utf-8">
三、快速自检清单 ✅
| 检查项 | 正确值 |
|---|---|
| PHP 文件 | UTF-8 无 BOM |
| Apache | UTF-8 |
| PHP header | utf-8 |
| MySQL server | utf8mb4 |
| DB / Table | utf8mb4 |
| 连接 | utf8mb4 |
| 浏览器 | UTF-8 |
四、如果你愿意,我可以更精准帮你
你可以补充:
- 乱码是 页面显示乱码 还是 数据库存进去乱码
- CentOS 版本(7 / 8 / Stream)
- 用的 MySQL / MariaDB
- PHP 版本
- 示例代码或截图
我可以直接帮你定位是哪一层出的问题。