Pis*_*3.0 4 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 already corrupt at this point
}
Run Code Online (Sandbox Code Playgroud)
由于我无法更改的原因,用户正在上载Windows-1250
charset中编码的文件- 单字节,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)