题
我有一个简单的脚本,该脚本接受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 />";
}
}
解决方案
您已经检查了 FGETCSV上的手册页面?没有什么可以谈论这个特定问题了,但是如果这里什么都没出现,也许值得一看。
例如,有:
注意:通过此功能考虑语言环境设置。如果lang是eg en_us.utf-8,则通过此函数读取单字节编码中的文件。
另外,看到它总是在生产线的开头,这是否真的是一个隐藏的线路问题?是这样:
注意:如果在Macintosh计算机上读取文件或创建文件时,PHP无法正确识别行结尾,则启用AUTO_DETECT_LINE_ENDINGS运行时配置选项可以帮助解决问题。
您可能还需要尝试使用不同的行结尾保存文件。
其他提示
您是否在打电话之前正确设置环境 fgetcsv()
?
setlocale(LC_ALL, 'fr_FR.UTF-8');
否则, fgetcsv()
不是多字节安全。
确保将其设置为可用地区列表中的内容。在Linux(当然在Debian上),您可以通过
locale -a
你应该得到像...
C
en_US.utf8
POSIX
对于UTF8支持,终点选择使用UTF8的编码。如果您的输入已编码其他内容,则需要使用适当的语言环境 - 但请确保您的操作系统首先支持它。
如果您将语言环境设置为系统上无法使用的语言环境,则无济于事。
我们看到了同样的结果 LANG
调成 C
, ,并通过确保将此类价值包裹在引号上来解决它。例如,行
a,"a",é,"é",óú,"óú",ó&ú,"ó&ú"
通过时生成以下数组 fgetcsv()
:
array (
0 => 'a',
1 => 'a',
2 => '',
3 => 'é',
4 => '',
5 => 'óú',
6 => '&ú',
7 => 'ó&ú',
)
当然,您必须通过将其加倍来避开该值中的任何引号,但这比修复缺失的字符要少得多。
奇怪的是,这在输入文件的UTF-8和CP1252编码中都会发生这种情况。