PHP技术问询:如何检测字符串编码为UTF-8或UTF-16LE
解决UTF-8与UTF-16LE编码检测的问题
我之前也踩过mb_detect_encoding检测UTF-16LE的坑,给你几个实用的解决方案:
1. 优先检查字节顺序标记(BOM)
UTF-16LE有明确的专属字节顺序标记\xFF\xFE,这是最直接可靠的判断依据。如果你的函数生成UTF-16LE内容时包含BOM,直接检查开头字节就能快速确定:
function isUtf16LeWithBom($str) { $bom = substr($str, 0, 2); return $bom === "\xFF\xFE"; }
如果你的函数目前没加BOM,也可以考虑在生成UTF-16LE内容时主动添加,这样检测逻辑会更清晰准确。
2. 用mb_check_encoding替代mb_detect_encoding
mb_detect_encoding是猜测编码类型,而mb_check_encoding是验证字符串是否符合指定编码,可靠性高得多。单元测试中你已经明确知道编码只可能是UTF-8或UTF-16LE,直接验证即可:
// 验证目标字符串是否为UTF-16LE if (mb_check_encoding($utf16Doc, 'UTF-16LE')) { echo "确认是UTF-16LE编码"; } else { echo "不是UTF-16LE编码"; }
这个方法在字符串包含非ASCII字符时几乎不会出错;就算是纯ASCII内容,UTF-16LE中ASCII字符\xXX\x00的字节结构也能被mb_check_encoding准确识别。
3. 修复mb_detect_encoding的使用方式
如果你坚持要用mb_detect_encoding,记得开启严格模式并指定编码检测顺序,避免函数误判:
$test = mb_detect_encoding($utf16Doc, ['UTF-16LE', 'UTF-8'], true); var_dump($test); // 现在应该能正确返回'UTF-16LE'
第三个参数设为true会启用严格检测,排除模棱两可的情况;同时把UTF-16LE放在检测顺序的第一位,优先验证该编码。
为什么你的原始代码会失败?
大概率是因为mb_detect_encoding默认没开启严格模式,当字符串内容比较简单(比如纯ASCII)时,它无法区分UTF-8和UTF-16LE的字节表示,所以返回false。
内容的提问来源于stack exchange,提问作者Tamara
相关产品推荐
相关产品推荐

