我有一个简单的脚本,它接受一个CSV文件并将每一行读入一个数组。然后我循环遍历第一行的每一列(在我的情况下,它包含调查问题)并打印出来。该调查采用法语,每当问题的第一个字符是特殊字符(é,ê,ç等)时,fgetcsv就会忽略它。
值中间的特殊字符只有在它们是第一个字符时才会受到影响。
我试图调试这个,但我很困惑。我用文件的内容做了一个var_dump,字符肯定在那里:
var_dump(utf8_encode(file_get_contents($_FILES['csv_file']['tmp_name'])));
这是我的代码:
if(file_exists($_FILES['csv_file']['tmp_name']) && $csv = fopen($_FILES['csv_file']['tmp_name'], "r"))
{
$csv_arr = array();
//Populate an array with all the cells of the CSV file
while(!feof($csv))
{
$csv_arr[] = fgetcsv($csv);
}
//Close the file, no longer needed
fclose($csv);
// This should cycle through the cells of the first row (questions)
foreach($csv_arr[0] as $question)
{
echo utf8_encode($question) . "<br />";
}
}
答案 0 :(得分:8)
在调用fgetcsv()
之前,您是否正确设置了区域设置?
setlocale(LC_ALL, 'fr_FR.UTF-8');
否则,fgetcsv()
不是多字节安全的。
确保将其设置为可用区域设置列表中显示的内容。在linux上(肯定是在debian上)你可以通过
看到这一点locale -a
你应该得到像......
C
en_US.utf8
POSIX
对于UTF8支持,最后选择utf8编码。如果你的输入是用其他东西编码的,你需要使用适当的语言环境 - 但要确保你的操作系统首先支持它。
如果您将区域设置设置为系统上不可用的区域设置,则无法帮助您。
答案 1 :(得分:2)
此行为已为其归档bug report,但显然是isn't a bug。
答案 2 :(得分:1)
您是否已查看manual page on fgetcsv?没有什么可以随便谈论这个特定的问题,但是如果没有任何问题,可能会有一些贡献值得一看。
就是这样,例如:
注意:此功能会考虑区域设置。如果LANG是例如en_US.UTF-8,此函数读取单字节编码的文件错误。
另外,看到它总是在行的开头,这可能是一个隐藏的换行问题吗?就是这样:
注意:如果在Macintosh计算机上读取文件或由Macintosh计算机创建文件时,PHP无法正确识别行结尾,则启用auto_detect_line_endings运行时配置选项可能有助于解决问题。
您可能还想尝试使用不同的行结尾保存文件。
答案 3 :(得分:1)
我们在LANG
设置为C
的情况下看到了相同的结果,并通过确保将这些值包装在引号中来解决此问题。例如,行
a,"a",é,"é",óú,"óú",ó&ú,"ó&ú"
在通过fgetcsv()
时生成以下数组:
array (
0 => 'a',
1 => 'a',
2 => '',
3 => 'é',
4 => '',
5 => 'óú',
6 => '&ú',
7 => 'ó&ú',
)
当然,你必须通过将它们加倍来逃避值中的任何引号,但这比修复丢失的字符要麻烦得多。
奇怪的是,输入文件的UTF-8和cp1252编码都会发生这种情况。