船说 CMS 网站搬家出现乱码怎么办
搬家后打开首页,正文变成一排问号或「测试」这样的怪字符——这篇会带你按「先看乱码长什么样,再定是哪一层出问题」的顺序,一步步把船说 CMS 的中文恢复正常。
第一步:先看乱码长什么样,确定排查方向
这一步要做的,是判断乱码发生在哪一层,因为不同样子的乱码对应完全不同的修法。
打开出问题的页面,右键选「查看页面源代码」,或者直接按 Ctrl+U,在源码里搜一段中文标题:
- 源码里是
???或???:数据在导入数据库时就已经丢了,问题出在导出/导入环节。 - 源码里是
测试、䏿–‡这种带重音符号的西欧字母:数据库里存的是好的 UTF-8,只是浏览器把它当成了 Latin-1 显示,问题出在页面声明的字符集或 HTTP 头。 - 源码里是
锟斤拷:原来存的是 GBK,被当成 UTF-8 又转回去,属于典型的多次错误转码,最难救,通常只能从旧库重新导出。 - 页面结构正常、只有标题或某个栏目乱:多半是模板文件本身编码不对,或者某个字段的表字符集和主表不一致。
注意:先别急着改数据库。只要还没确认源码里的实际字节,动手改很可能让
测试变成不可逆的锟斤拷。改库之前先做一次完整备份。
第二步:确认数据库实际存的内容和字符集
这一步是为了看清楚「库里到底存了什么」以及「表和字段用什么字符集」。
用 phpMyAdmin 或 Navicat 连上搬家后的数据库,执行:
SHOW VARIABLES LIKE 'character_set%';
SHOW CREATE TABLE cs_article;
看 character_set_database、character_set_server 是不是 utf8mb4,以及建表语句末尾的 DEFAULT CHARSET。如果表是 latin1 或 gbk,而内容其实是 UTF-8,就会出现第二步里说的西欧字母现象。
如果是整库字符集不对,可以先改库,再改表:
ALTER DATABASE chuanshuo DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
表建议一张张来,别一把梭:
ALTER TABLE cs_article CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
注意:
CONVERT TO会真的转换字节内容。如果数据本身已经是 UTF-8 而只是字段声明成了 latin1,要改用ALTER TABLE cs_article DEFAULT CHARSET=utf8mb4;(不带 CONVERT),否则会把好数据转坏。不确定时先拿一张表试验。
第三步:重做一次导出导入,全程指定 utf8mb4
这一步是解决 ??? 类乱码的根本办法——重新搬一次数据。
在旧服务器上导出(不要用 phpMyAdmin 的「快速导出」,它常按默认字符集走):
mysqldump --default-character-set=utf8mb4 -u root -p --single-transaction chuanshuo > chuanshuo.sql
在新服务器导入:
mysql --default-character-set=utf8mb4 -u root -p chuanshuo < chuanshuo.sql
注意:千万别用 Windows 记事本打开这个 .sql 再「另存为」。记事本默认会存成带 BOM 的 UTF-8 或 ANSI,中文会当场报废。要改就用 VS Code。
第四步:检查船说 CMS 的数据库配置文件
这一步改的是 PHP 连接数据库时握手用的字符集。
用 VS Code 打开站点根目录下的配置文件,常见位置是 config/database.php、application/database.php 或 data/config.php(不同版本目录名不同,用编辑器的全局搜索搜 charset 就能定位)。
把连接参数里的字符集从 utf8 改成 utf8mb4:
'charset' => 'utf8mb4',
如果文件里是手写连接,确认在 mysqli_connect 之后有一句:
mysqli_set_charset($conn, 'utf8mb4');
或 $pdo->exec("SET NAMES utf8mb4");。
注意:MySQL 里的
utf8其实是utf8mb3,一个字符最多 3 字节,存 emoji 和部分生僻字会直接坏掉。搬家正好是换掉它的时机。
第五步:检查 PHP 文件和模板的编码、BOM 与 HTTP 头
这一步解决「库是对的、页面还是乱」的情况。
用 VS Code 打开乱码对应的模板文件(一般在 template/ 或 templates/ 目录下),点右下角的编码标识(默认显示 UTF-8 或 GB2312),选「通过编码保存」→ UTF-8。保存后再看右下角,确认显示的是 UTF-8 而不是 UTF-8 with BOM。如果有 BOM,再点一次,选「以 UTF-8 无 BOM 保存」。
接着确认页面头部有字符集声明:
<meta charset="utf-8">
并检查 PHP 里有没有 header('Content-Type: text/html; charset=utf-8');,两者要一致。
服务器层面也顺手对齐:Nginx 在 server 块里加 charset utf-8;,Apache 加 AddDefaultCharset UTF-8。
注意:PHP 文件如果带 BOM,页面最前面会多出三个不可见字节,浏览器可能据此把整页按 GBK 解析,同时还会引发「headers already sent」报错。这个坑很常见,务必检查。
第六步:清掉旧缓存再验证
这一步是因为缓存文件是搬家前生成的,里面存的是旧编码内容,不清掉你会以为没修好。
先进后台,通常在「系统」→「系统设置」里有「清除缓存」或「更新缓存」按钮,点一次。再登录服务器,删除站点根目录下的缓存目录,常见的是 runtime/cache、data/cache、cache/:
rm -rf runtime/cache/* data/cache/*
然后重新打开首页,按 Ctrl+F5 强制刷新(绕过浏览器缓存)验证。
小结
- 先看源码判断乱码类型:
???是数据丢失,测试是显示层字符集不对,锟斤拷基本只能重导。 - 所有导出导入命令都要显式加上
--default-character-set=utf8mb4,不要用 phpMyAdmin 快速导出。 ALTER TABLE ... CONVERT TO和DEFAULT CHARSET=语义不同,用错会把好数据转坏,改前必须备份。- 配置文件里的
utf8建议统一换成utf8mb4,utf8其实是存不全的utf8mb3。 - PHP 文件和模板要用「UTF-8 无 BOM」保存,页面的
meta charset与 HTTP 头要一致。 - 最后一定清
runtime/cache一类缓存目录,否则改了数据库也看不到效果。
原文链接:https://www.gj0.com/thread-578.html
转载请注明出处并保留本声明;内容仅代表作者观点,与本站立场无关。若本文涉嫌侵权,请联系本站处理。