Php fgetcsv()删除带有变音符号(即非ASCII)的字符-如何修复?

Php fgetcsv()删除带有变音符号(即非ASCII)的字符-如何修复?,php,csv,character-encoding,Php,Csv,Character Encoding,类似问题: , 我的应用程序有一个表单,用户可以上传一个CSV文件(它的5个内部用户总是上传一个有效的文件-逗号分隔、引号、记录以LF结尾),然后使用PHP将文件导入数据库: $fhandle = fopen($uploaded_file,'r'); while($row = fgetcsv($fhandle, 0, ',', '"', '\\')) { print_r($row); // further code not relevant as the data is alr

类似问题:

我的应用程序有一个表单,用户可以上传一个CSV文件(它的5个内部用户总是上传一个有效的文件-逗号分隔、引号、记录以LF结尾),然后使用PHP将文件导入数据库:

$fhandle = fopen($uploaded_file,'r');
while($row = fgetcsv($fhandle, 0, ',', '"', '\\')) {
    print_r($row);
    // further code not relevant as the data is already corrupt at this point
}
由于无法更改的原因,用户正在上载以
Windows-1250
charset编码的文件-单字节8位字符编码

问题是:
fgetcsv()
中删除了127(“扩展ASCII”)以外的一些(不是全部!)字符。示例数据:

"15","Ústav"
"420","Špičák"
"7","Tmaň"
变成

Array (
  0 => 15
  1 => "stav"
)
Array (
  0 => 420
  1 => "pičák"
)
Array (
  0 => 7
  1 => "Tma"
)
(注意,
č
被保留,但
Ú
被删除)


的文档说“因为4.3.5 fgetcsv()现在是二进制安全的”,但看起来不是。是我做错了什么,还是这个函数坏了,我应该寻找一种不同的方法来解析CSV?

结果是我没有很好地阅读文档-fgetcsv()只是在某种程度上是二进制安全的。对于纯ASCII<127是安全的,但是:

注:

将考虑区域设置 通过这个函数。如果朗是。 en_US.UTF-8,一个字节中的文件 通过这种方式读取的编码是错误的 作用

换句话说,fgetcsv()试图实现二进制安全,但实际上它不是(因为它同时也会弄乱字符集),而且它可能会损坏它读取的数据(因为此设置不是在php.ini中配置的,而是从
$LANG
读取的)

我通过读取带有
fgets
的行(它可以处理字节,而不是字符)并使用将它们解析为数组,从而避开了这个问题:

$fhandle = fopen($uploaded_file,'r');
while($raw_row = fgets($fhandle)) { // fgets is actually binary safe
    $row = csvstring_to_array($raw_row, ',', '"', "\n");
    // $row is now read correctly
}

我马上回答,这只虫子早些时候咬了我,找到了原因;希望与SO分享这一点,因为错误很微妙。(澄清一下,Win-1250只是输入编码。数据稍后转换并以UTF-8的形式存储在数据库中;该部分工作正常。最初读取的数据是问题所在。)错误:fgets lenght必须大于0,并且csvstring_to_数组不存在错误:如果未定义它,它当然不存在-它需要显式定义,它不是内置的。“使用评论中的CSV功能”和链接不清楚?