如何使用PHP检测文本文件的Unicode编码(UTF-8或UTF-16)
PHP检测UTF-8/UTF-16编码的实现方法
有简便可行的实现方案,核心逻辑是先检测文件头的BOM标记,无BOM时通过编码规则校验即可覆盖绝大多数场景,具体实现如下:
- 核心检测逻辑
- 优先读取文件前3个字节匹配字节顺序标记(BOM):带BOM的文件可以100%准确判定,对应关系为:
\xEF\xBB\xBF对应 UTF-8\xFF\xFE对应 UTF-16LE(小端序)\xFE\xFF对应 UTF-16BE(大端序)
- 无BOM时调用PHP内置的编码校验函数验证字节流合法性:先校验是否符合UTF-8编码规则,若不符合再校验是否符合UTF-16大小端的编码规则即可。
- 优先读取文件前3个字节匹配字节顺序标记(BOM):带BOM的文件可以100%准确判定,对应关系为:
- 可直接复用的代码示例
function detectUnicodeEncoding(string $filePath): ?string { // 仅读取前1024字节即可完成检测,避免大文件占用过多内存 $content = file_get_contents($filePath, false, null, 0, 1024); if ($content === false) return null; // BOM检测逻辑 if (str_starts_with($content, "\xEF\xBB\xBF")) return 'UTF-8'; if (str_starts_with($content, "\xFF\xFE")) return 'UTF-16LE'; if (str_starts_with($content, "\xFE\xFF")) return 'UTF-16BE'; // 无BOM时优先校验UTF-8 if (mb_check_encoding($content, 'UTF-8')) { return 'UTF-8'; } // UTF-16字节长度必然是偶数,先过滤不符合规则的情况 $byteLength = strlen($content); if ($byteLength % 2 !== 0) { return null; } // 校验UTF-16大小端合法性 if (mb_check_encoding($content, 'UTF-16LE')) { return 'UTF-16LE'; } if (mb_check_encoding($content, 'UTF-16BE')) { return 'UTF-16BE'; } // 不属于目标编码类型 return null; }
注意:纯ASCII内容的无BOM文件会被判定为UTF-8,这是因为ASCII本身是UTF-8的子集,这种场景下判定为UTF-8不会影响后续内容读取。如果有特殊需求需要区分纯ASCII类的UTF-16文件,可以额外增加规则:统计内容中0x00字节的占比,占比接近50%的大概率为UTF-16编码。
内容的提问来源于stack exchange,提问作者Richi RM
相关产品推荐
相关产品推荐

