Php fgetcsv()忽略位于行首的特殊字符!

Php fgetcsv()忽略位于行首的特殊字符!,php,csv,fgetcsv,Php,Csv,Fgetcsv,我有一个简单的脚本,它接受CSV文件并将每一行读取到一个数组中。然后我循环浏览第一行的每一列(在我的例子中,它包含调查的问题),然后打印出来。调查是用法语进行的,只要问题的第一个字符是特殊字符(é、ê、ç等),fgetcsv就会忽略它 只有在第一个字符时,中间值中的特殊字符才会受到影响。 我试图调试这个,但我感到困惑。我对文件的内容进行了var_转储,字符肯定在那里: var_dump(utf8_encode(file_get_contents($_FILES['csv_file']['tmp_

我有一个简单的脚本,它接受CSV文件并将每一行读取到一个数组中。然后我循环浏览第一行的每一列(在我的例子中,它包含调查的问题),然后打印出来。调查是用法语进行的,只要问题的第一个字符是特殊字符(é、ê、ç等),fgetcsv就会忽略它

只有在第一个字符时,中间值中的特殊字符才会受到影响。

我试图调试这个,但我感到困惑。我对文件的内容进行了var_转储,字符肯定在那里:

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 />";
        }

    }
如果(文件存在($\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
{
$csv_arr=array();
//用CSV文件的所有单元格填充数组
而(!feof($csv))
{
$csv_arr[]=fgetcsv($csv);
}
//关闭文件,不再需要
现金流量表(csv);
//这应该在第一行的单元格中循环(问题)
foreach($csv_arr[0]作为$question)
{
echo utf8_编码($question)。“
”; } }
您已经签出了吗?没有什么可以马上讨论这个特定的问题,但是如果这里没有任何问题的话,一些贡献可能值得一看

比如说:

注意:此函数将考虑区域设置。如果LANG是例如en_US.UTF-8,则此函数会错误读取单字节编码的文件

另外,由于它总是在行首,这真的是一个隐藏的断线问题吗?这是:

注意:如果PHP在读取Macintosh计算机上或由Macintosh计算机创建的文件时无法正确识别行尾,启用自动检测行尾运行时配置选项可能有助于解决此问题


您可能还想尝试用不同的行尾保存文件。

在调用
fgetcsv()
之前,您是否正确设置了区域设置

否则,
fgetcsv()
不是多字节安全的

确保将其设置为显示在可用区域设置列表中的某个内容。在linux上(当然是在debian上),您可以通过

locale -a
你应该得到像

C
en_US.utf8
POSIX
对于UTF8支持,请选择末尾带有UTF8的编码。如果您的输入是用其他东西编码的,您需要使用适当的语言环境,但首先要确保您的操作系统支持它


如果您将区域设置为系统上不可用的区域设置,则不会对您有任何帮助。

此行为有一个字段,但显然是这样。

我们看到了将
LANG
设置为
C
时的相同结果,并通过确保这些值用引号括起来来解决此问题。例如,该行

a,"a",é,"é",óú,"óú",ó&ú,"ó&ú"
通过
fgetcsv()
时生成以下数组:

当然,您必须通过将值中的任何引号加倍来避开它们,但这比修复丢失的字符要简单得多


奇怪的是,输入文件的UTF-8和cp1252编码都会出现这种情况。

我已经阅读了有关如何使用该功能的手册页面,在注释区域快速搜索并没有弹出任何特殊字符或UTF-8编码。我注意到UTF-8编码可能有问题,但如果我不编码值,值仍然不会显示。我不确定是否还有其他办法来解决这个问题。我尝试使用“|”作为行尾分隔符,但我遇到了同样的问题。这是非常令人困惑的:)对不起,如果我说我无知,但什么是安全的?我添加了这行代码,但对脚本的行为没有任何影响。手册说该函数是二进制安全的,因为PHP 4.3.5(我们安装了PHP 5)多字节安全=能够处理单个字符可以包含多个字节的编码(例如UTF-8)。这解决了我的问题,只要输入是UTF-8,但问题仍然存在于其他8位编码中。答案很好-在整个项目中将locale设置为UTF-8编码而不是仅针对
fgetcsv()
?fgetcsv()只有在使用纯ASCII时才是二进制安全的-换句话说,根本不是。请参见-基本上,使用fgets()读取数据,然后使用自定义函数解析CSV。显然,这也是可行的:它不是一个bug,而是一个特性。这一定是个笑话。
a,"a",é,"é",óú,"óú",ó&ú,"ó&ú"
array (
  0 => 'a',
  1 => 'a',
  2 => '',
  3 => 'é',
  4 => '',
  5 => 'óú',
  6 => '&ú',
  7 => 'ó&ú',
)