因为某些原因现在需要批量检测文件编码,看看是不是有非 UTF-8 文件混在其中
我当然是首选了我最熟悉的 PHP,感觉应该很简单
google 搜索 php detect encoding,第一个就是 PHP 官方文档 mb_detect_encoding – Manual – PHP
于是按照文档有样学样,拿个 UTF-8 文件测试一下
echo mb_detect_encoding( file_get_contents('./utf8.txt') );
当我满心以为会显示 UTF-8 的时候,看到的却是 ASCII
几经核实、尝试,发现即便我传个 'test'
进去都会返回 ASCII。只有字符串中包含汉字等非 ASCII 字符时才会返回 UTF-8。围绕这个函数搜索了一下,也看到不少说这玩意儿不靠谱的言论。不能说它错,但返回值确实不符合直觉
继续找方案,甚至还发现了用 BOM 来判断是否 UTF-8 的操作,这个更不靠谱😂
除此之外见得最多的主流(抄来抄去)解决方案是
function detect_encoding($file) {
$list = array('GBK', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'ISO-8859-1');
$str = file_get_contents($file);
foreach ($list as $item) {
$tmp = mb_convert_encoding($str, $item, $item);
if (md5($tmp) == md5($str)) {
return $item;
}
}
return null;
}
通过对比转换前后的字符串是否相等来判断编码,也确实是个办法
不过对于我现在只需要判断是否 UTF-8 的需求来说没这个必要
我又把目光放回到 mb_detect_encoding
,注意到它的第二个参数 encoding_list
当被测字符串的编码不在这个参数之中时函数返回 false
这个参数的默认值为 mb_detect_order()
,经测试该函数的返回值为 ['ASCII', 'UTF-8']
噢,我好像破案了 —— 当文件同时满足多种条件时,函数只返回第一个编码名称
因此只要将 UTF-8 放到最前面,或者只提供 UTF-8 即可
可以,Windos系统倒无所谓,遇到linux,有时直接用txt打开,很容易出问题,这个倒是可以检查下