file_get_contents读中文乱码的根本原因是未明确指定文件编码,需先用file -i或编辑器确认真实编码,再通过转存utf-8、mb_convert_encoding或stream_filter_append等方式统一为utf-8处理。

file_get_contents 读中文文件出乱码,不是函数本身的问题,而是你没告诉 PHP “这文件到底是什么编码”。
PHP 不会猜编码,它只负责把文件原样读成字节流。如果源文件是 GBK,而你直接 echo 到 UTF-8 页面,浏览器就拿 GBK 字节当 UTF-8 解——结果必然是问号、方块或一堆“”。
怎么确认源文件真实编码?
- Linux/macOS 下用:
file -i your_file.txt
看输出里charset=后面是什么(如gbk、utf-8),注意是否带 BOM(with bom是雷区) - VS Code 右下角显示 “GBK” 或 “UTF-8 with BOM”,就说明编码不干净
- Notepad++:菜单栏 → 编码 → 查看当前编码类型
读取时必须显式处理编码转换
file_get_contents 本身不支持自动转码,常见靠谱做法只有三种:
首选:把源文件先转成 UTF-8 无 BOM
用 VS Code 或 Notepad++ 打开 → 另存为 → 编码选 “UTF-8(不带 BOM)” → 覆盖保存
后续 PHP 就能直接echo file_get_contents('a.txt'),无需额外转换次选:用
mb_convert_encoding转
你得知道源编码,比如是 GBK:$content = mb_convert_encoding(file_get_contents('a.txt'), 'UTF-8', 'GBK');
注意顺序:目标编码在前,源编码在后;'auto'不可靠,别依赖硬核但可控:用
stream_filter_append加过滤器$fp = fopen('a.txt', 'r'); stream_filter_append($fp, 'convert.iconv.GBK/UTF-8');
然后fread($fp, filesize('a.txt'))
这种方式避免一次性加载大文件到内存,适合处理几百 MB 的日志类文本
容易踩的坑
-
iconv('GBK', 'UTF-8', $str)遇到非法字节会报错,加//IGNORE更稳:iconv('GBK', 'UTF-8//IGNORE', $str) -
mb_convert_encoding第三个参数写成'auto',在含混合编码的文件里大概率失效 - 没检查源文件 BOM:GBK 文件带 BOM 会导致
mb_convert_encoding识别失败,先用hexdump -C a.txt | head看开头三字节是不是ef bb bf - 忘了输出前设响应头:
header('Content-Type: text/html; charset=utf-8')缺失,浏览器仍按默认 ISO-8859-1 解析,前面所有转码白干
真正麻烦的从来不是怎么转,而是你根本不知道原始文件到底是什么编码——尤其当文件来自 Windows 记事本、旧系统导出或第三方 API 返回时。先查清源头,再选方案,比堆 mb_* 函数更省时间。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











