我有点喜欢
编码。我有一个允许用户上传csv文件的php文件。
我的问题是,当使用 excel for mac 创建文件时,如果文件包含 utf-8 字符(如重音字母),我的代码将无法正常工作。基本上它会忽略重音字符。
仅当使用 Comma separated values
选项保存文件时,才会出现问题。
所有其他情况下,例如在Windows中制作的文件或使用开放式办公室甚至在Mac上使用excel,但将它们保存为"Windows"文件不会造成任何问题。
mb_detect_encoding
为导致问题的文件返回 false。
这是代码:
// say there is the word Nestlé in the file
$content = file_get_contents(addslashes($file_name));
var_dump(mb_detect_encoding($content)); // print false
$data = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
//$data = utf8_encode($content); //doesn't work
var_dump($data); // print Nestl
ini_set('auto_detect_line_endings',TRUE);
// more code here we don't need at the moment
这个问题给了我一些指示: file_get_contents() 分解 UTF-8 字符
关于如何解决此问题的任何帮助或想法?提前谢谢你
这是安东尼发布的回复后的新代码
$content = file_get_contents(addslashes($file_name));
// i have no control on how the file is generated so i need to to the replace in the code
$content = str_replace(",", "'t", $content);
var_dump($content);
$data = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
$data = mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');
$data = chr(255) . chr(254) . $data;
var_dump($data); // this still print funny characters not the accented letter
我做错了什么吗?
这是特定于 Excel 的问题,在 Excel for Mac 上更为常见,其中 UTF-8 多字节字符无法正确显示。您可以使用其他电子表格查看器(例如 Google 表格)进行确认。
此问题的解决方法是:
-
使用制表符(
't
)而不是逗号作为分隔符(别担心,它在技术上仍然是CSV)。 -
编码为 utf-8 后,将整个 csv 字符串转换为 UTF-16LE :
mb_convert_encoding($csv_content, 'UTF-16LE', 'UTF-8');
-
在 csv 字符串前面加上一个小端字节顺序标记 (LE BOM):
$csv_content = chr(255) . chr(254) . $csv_content;
这应该可以做到。
好的,谢谢安东尼,这是可以修复它的行:
$data = iconv('macintosh', 'UTF-8', $content);
所以我的最终代码将如下所示:
enter code here
$content = file_get_contents(addslashes($file_name));
var_dump(mb_detect_encoding($content));
// need to do this for an issue specific to Excel and more common on Excel for Mac
// using excel on mac if the file is saved as csv using the Comma separated values option we need to use iconv and not mb_convert_encoding
// we use mb_detect_encoding because the content of such file returns a false value
if(!mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true)){
//$data = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', 'macintosh', true));
$data = iconv('macintosh', 'UTF-8', $content);
}
// deal with known encoding types
else{
$data = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
}