fgetcsv()使用变音符号(即非ASCII)删除字符 - 如何修复?

Pis*_*3.0 4 php csv character-encoding

类似的问题:
在PHP fgetcsv()期间不读取CSV文件中的某些字符,
fgetcsv()在行的开头忽略特殊字符

我的应用程序有一个表单,用户可以上传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
}
Run Code Online (Sandbox Code Playgroud)

由于我无法更改的原因,用户正在上载Windows-1250charset中编码的文件- 单字节,8位字符编码.

问题:并且有一些(不是全部!)字符超过127("扩展ASCII")fgetcsv().示例数据:

"15","Ústav"
"420","Špi?ák"
"7","Tma?"
Run Code Online (Sandbox Code Playgroud)

Array (
  0 => 15
  1 => "stav"
)
Array (
  0 => 420
  1 => "pi?ák"
)
Array (
  0 => 7
  1 => "Tma"
)
Run Code Online (Sandbox Code Playgroud)

(注意?保留,但Ú被删除)

fgetcsv的文档说"自4.3.5 fgetcsv()现在是二进制安全",但看起来并非如此.我做错了什么,或者这个功能被破坏了,我应该寻找一种不同的方式来解析CSV?

Pis*_*3.0 13

事实证明,我没有充分阅读文档 - fgetcsv()只是一些二进制安全.普通的ASCII <127是安全的,但文档也说:

注意:

此功能考虑了区域设置.如果LANG是例如en_US.UTF-8,则此函数读取单字节编码的文件错误

换句话说,fgetcsv()试图是二进制安全的,但它实际上并不是(因为它同时也在混乱charset),它可能会破坏它读取的数据(因为这个设置没有在php中配置) .ini,而是从中读取$LANG).

我通过读取fgets(使用字节,而不是字符)和使用文档中的注释中的CSV函数来解析问题,将它们解析为数组:

$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
}
Run Code Online (Sandbox Code Playgroud)