4

PHP 检测文件编码的不完美解决方案

 2 years ago
source link: https://www.mokeyjay.com/archives/2721/comment-page-2
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

PHP 检测文件编码的不完美解决方案

因为某些原因现在需要批量检测文件编码,看看是不是有非 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 即可

本站文章除注明转载外,均为原创文章。如需转载请注明出处:https://www.mokeyjay.com/archives/2721

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK