PHP上传带UTF8重音字符的CSV文件读取时字符丢失问题咨询
问题原因
- 你上传的CSV文件是Excel导出的,默认编码为*Windows-1252(西欧编码)*或ISO-8859-1,并非你预期的UTF-8编码
- 直接用
file()函数按UTF-8规则读取时,重音字符的特殊字节会被判定为无效字符被丢弃,就出现了Cédric变成Cdric的问题,Excel打开正常是因为它自动识别到了文件的原始编码
解决方案
读取每行内容后,先将编码从原始编码转换为UTF-8即可,修改你的数据读取代码如下:
$files = file('upload/' . $inputFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); foreach (array_slice($files, 1, 5000) as $datas){ // 新增编码转换逻辑,Windows-1252兼容ISO-8859-1,覆盖绝大多数西欧CSV的情况 $datas = mb_convert_encoding($datas, 'UTF-8', 'Windows-1252'); $data = explode(';', $datas); var_dump($data[0]); die(); }
如果上面的转换还有问题,可以换用iconv函数实现转换:
$datas = iconv('Windows-1252', 'UTF-8//IGNORE//TRANSLIT', $datas);
可选优化(兼容带BOM的UTF-8 CSV)
如果部分用户上传的是带BOM头的UTF-8格式CSV,可以额外加一步去除BOM头的逻辑,避免首行数据解析异常:
function remove_utf8_bom($text) { $bom = pack('H*','EFBBBF'); return preg_replace("/^$bom/", '', $text); } // 编码转换后调用即可 $datas = remove_utf8_bom($datas);
注意事项
- 如果你的CSV面向多语言用户,可以在上传页面提示用户导出CSV时选择UTF-8编码格式,从源头避免编码问题
- 不确定文件原始编码时,可以使用
mb_detect_encoding($datas, ['UTF-8', 'Windows-1252', 'ISO-8859-1'])自动检测源编码再进行转换,兼容性更强
内容的提问来源于stack exchange,提问作者Cohchi
相关产品推荐
相关产品推荐

