本文目录导读:

PHP项目迁移后出现编码乱码,通常是因为文件编码、数据库连接编码或页面输出编码三者之间不一致导致的,以下是系统的排查和解决方法:
检查并统一文件编码
首先确认所有PHP文件的编码格式:
# Linux/Mac 查看文件编码 file -i yourfile.php # 或使用编辑器查看
解决方案:将所有文件统一为 UTF-8(无BOM)
// 使用编辑器(VS Code、Sublime等)重新保存为 UTF-8 without BOM // 或者用代码批量转换
设置页面输出编码
在PHP文件头部添加:
<?php
// 设置HTTP头
header('Content-Type: text/html; charset=utf-8');
// 或者使用HTML meta标签
echo '<meta charset="UTF-8">';
?>
配置数据库连接编码
MySQL 连接编码设置:
<?php
// PDO 方式
$dsn = 'mysql:host=localhost;dbname=test;charset=utf8'; // 注意是 utf8 不是 utf-8
$pdo = new PDO($dsn, $user, $pass, [
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4"
]);
// mysqli 方式
$mysqli = new mysqli($host, $user, $pass, $db);
$mysqli->set_charset('utf8mb4');
// 或者执行SQL
$mysqli->query("SET NAMES utf8mb4");
?>
检查数据库和表的编码:
-- 查看数据库编码 SHOW CREATE DATABASE your_database; -- 查看表编码 SHOW CREATE TABLE your_table; -- 修改数据库编码 ALTER DATABASE your_database CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 修改表编码 ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
处理已存在的乱码数据
如果数据库已有乱码数据,需要修复:
-- 查看当前编码 SELECT HEX(content) FROM your_table LIMIT 1; -- 如果数据是双编码(utf8->utf8的utf8),修复命令 UPDATE your_table SET content = CONVERT(CAST(CONVERT(content USING latin1) AS BINARY) USING utf8);
配置文件编码设置
php.ini 配置:
default_charset = "UTF-8" mbstring.internal_encoding = UTF-8 mbstring.http_input = UTF-8 mbstring.http_output = UTF-8
.htaccess 设置(Apache):
AddDefaultCharset UTF-8
JSON 输出处理
<?php
// JSON输出时指定编码
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE);
// 或者设置 mbstring 扩展
mb_internal_encoding('UTF-8');
?>
表单提交处理
<?php
// 接收表单数据时
$_POST = array_map(function($item) {
return mb_convert_encoding($item, 'UTF-8', 'auto');
}, $_POST);
?>
快速诊断脚本
创建一个测试文件 encoding_test.php:
<?php
header('Content-Type: text/html; charset=utf-8');
echo "文件编码测试<br>";
echo "中文测试:你好,世界!<br>";
// 数据库测试
$db = new mysqli('localhost', 'user', 'pass', 'db');
$db->set_charset('utf8mb4');
$result = $db->query("SELECT '中文测试' as test");
$row = $result->fetch_assoc();
echo "数据库编码测试:".$row['test'];
?>
批量处理脚本
修复所有乱码数据的PHP脚本示例:
<?php
// 批量修复数据库编码
$db = new mysqli($host, $user, $pass, $db);
$db->set_charset('latin1'); // 假设当前数据库实际编码是latin1
$result = $db->query("SELECT id, content FROM your_table");
while ($row = $result->fetch_assoc()) {
$fixed = mb_convert_encoding($row['content'], 'UTF-8', 'latin1');
$stmt = $db->prepare("UPDATE your_table SET content = ? WHERE id = ?");
$stmt->bind_param('si', $fixed, $row['id']);
$stmt->execute();
}
?>
常见问题速查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 问号乱码(???) | 数据库字段编码不支持该字符 | 改用 utf8mb4 编码 |
| 方框乱码(□□□) | 缺少中文字体 | 安装中文字体包 |
| 完全乱码 | 编码不统一 | 统一使用 UTF-8 |
| 部分乱码 | 混合编码 | 检测并转换 |
最佳实践建议
- 统一编码:所有环节使用 UTF-8
- 备份数据:修改前先备份数据库
- 逐步测试:每次修改后检查效果
- 配置文件:在配置文件中设置默认编码
- 使用框架:现代框架通常会自动处理编码问题
如果以上方法还不能解决,建议提供具体的乱码表现(截图或字符编码值),可以更精准地诊断问题。