在我的应用程序中,我读取了一个csv文件并向用户显示内容。但是编码存在问题。
我有两个csv文件 example1.csv 和 example2.csv 。我在notepad ++中都打开了,它显示了example1的ANSI编码和没有BOM的UTF-8(例如2)。
首先,我尝试使用mb_detect_encoding函数来检测编码,但在两种情况下都显示UTF-8,这是不正确的。
其次,我尝试使用utf8_encode将文件内容转换为UTF-8。这适用于ANSI文件。但是对于没有BOM文件的UTF-8,似乎它被编码回ANSI。它显示Ã而不是德语ß。与其他特殊字符相同。
我希望在显示或处理内容之前确保内容始终采用UTF-8格式。那么我做错了什么吗?
这就是我使用mb_detect_encoding函数的方法:
$file_content = file_get_contents($_FILES['file']['tmp_name']);
die(var_dump( mb_detect_encoding($file_content)));
并为两个示例打印UTF-8。
答案 0 :(得分:10)
无法以100%的准确度和/或信心检测未知文本的编码。
在实践中,会出现各种可能结果的情况:您可以非常肯定UTF-8中的多语言文本将被正确地检测到,同时很难检测出ISO系列中的哪一个。 -8859编码对应于某些文本 - 除非您愿意进行统计分析,否则甚至无法做出有根据的猜测!
有了这个,让我们看看你可以做什么。首先,除非你将自定义工具带入战斗,否则mb_detect_encoding
可以为你做什么。不幸的是,这不是很多。姐妹函数mb_detect_order
的文档说明:
mbstring目前实现以下编码检测 过滤器。如果以下内容存在无效的字节序列 编码,编码检测将失败。
UTF-8,UTF-7,ASCII,EUC-JP,SJIS,eucJP-win,SJIS-win,JIS, ISO-2022-JP。
对于ISO-8859-X,mbstring始终检测为ISO-8859-X。
对于UTF-16,UTF-32,UCS2和UCS4,编码检测将失败 总是
因此,对日文编码进行折扣,您基本上可以区分UTF-8,UTF-7和ASCII。您无法检测ISO-8859-X,因为如果您考虑将任何文本“识别”为任何这些编码(即您将100%错误)积极率 - 不好,而且包含UTF-16的群体根本不受支持。
不幸的是,坏消息并未就此结束。 编码的顺序也很重要!由于以UTF-7或ASCII编码的文本也是有效的UTF-8,因此将UTF-8放在候选列表的前面将确保这是您将获得的唯一结果 - 因此必须不惜一切代价避免它。
由于默认检测顺序依赖于php.ini setting,因此您绝对不应该依赖它并通过设置自己的检测顺序进入已知状态:
mb_detect_order('ASCII, UTF-8'); // I left UTF-7 out, but who cares?
所以你至少可以判断你的文字是ASCII还是UTF-8,对吧?好吧,不。除非你特别要求当你说“UTF-8”时,你的意思是:
$valid_utf8 = "\xC2\xA2";
$invalid_utf8 = "\xC2\x00";
mb_detect_order('UTF-8');
echo mb_detect_encoding($valid_utf8); // "utf-8": correct
echo mb_detect_encoding($invalid_utf8); // "utf-8": WTF?!?!?!
上述问题是,除非您为true
参数传递$strict
,否则检测到UTF-8会有点过于乐观。
这是最好的 - 检测编码的正确方法(只是在这里几乎无法使用复数):
$valid_utf8 = "\xC2\xA2";
$invalid_utf8 = "\xC2\x00";
$ascii = "hello world";
mb_detect_order('ASCII, UTF-8');
echo mb_detect_encoding($valid_utf8, mb_detect_order(), true); // OK: "utf-8"
echo mb_detect_encoding($invalid_utf8, mb_detect_order(), true); // OK: false
echo mb_detect_encoding($ascii, mb_detect_order(), true); // OK: "ascii"
除非你有关于该文字的带外信息,否则没有。
好的,这不完全正确。在实践中你可以做一些事情:
答案 1 :(得分:-1)
检查utf8做这样的事情
if (mb_check_encoding(file_get_contents($file), 'UTF-8')) {
// yup, all UTF-8
}