我正在使用php中的csv导入脚本。它工作正常,除了字段开头的外来字符。
代码看起来像这样
if (($handle = fopen($filename, "r")) !== FALSE)
{
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE)
$teljing[] = $data;
fclose($handle);
}
以下是显示我的问题的数据示例
føroyskir stavir, "Kr. 201,50"
óvirkin ting, "Kr. 100,00"
这将导致以下
array
(
[0] => array
(
[0] => 'føroyskir stavir',
[1] => 'Kr. 201,50'
)
[1] => array
(
[0] => 'virkin ting', <--- Should be 'óvirkin ting'
[1] => 'Kr. 100,00'
)
)
我已经在php.net的一些评论中看到了这种行为,我尝试ini_set('auto_detect_line_endings',TRUE);
来检测行结尾。没有成功。
有谁熟悉这个问题?
编辑:
谢谢你,这个问题现在已经解决了。
setlocale(LC_ALL, 'en_US.UTF-8');
是解决方案。
答案 0 :(得分:6)
来自fgetcsv()
的{{3}}:
“注意:此功能会考虑区域设置。如果LANG是例如en_US.UTF-8,则此功能会读取单字节编码的文件错误。”
答案 1 :(得分:0)
从PHP.net/fgetcsv评论中复制:
keke at marketruler dot com 04-Feb-2010 11:18请注意fgetcsv, 至少在PHP 5.3或之前,将 不适用于UTF-16编码文件。 你的选择是转换整个 归档到ISO-8859-1(或latin1),或 逐行转换并转换每一个 然后进入ISO-8859-1编码行 使用str_getcsv(或兼容 向后兼容的实现)。 如果你需要阅读非拉丁语 字母表,可能最好转换为 UTF-8。
请参阅str_getcsv了解 向后兼容的版本 用PHP&lt; 5.3,并查看utf8_decode 对于Rasmus写的函数 Andersson提供utf16_decode。 我添加的修改是 BOP出现在文件的顶部, 然后不在后续行。那么你 需要存储endian-ness,和 然后在每次后续重新发送 线解码。这个修改版本 返回字节序,如果不是 可用的:
<?php
/**
* Decode UTF-16 encoded strings.
*
* Can handle both BOM'ed data and un-BOM'ed data.
* Assumes Big-Endian byte order if no BOM is available.
* From: http://php.net/manual/en/function.utf8-decode.php
*
* @param string $str UTF-16 encoded data to decode.
* @return string UTF-8 / ISO encoded data.
* @access public
* @version 0.1 / 2005-01-19
* @author Rasmus Andersson {@link http://rasmusandersson.se/}
* @package Groupies
*/
function utf16_decode($str, &$be=null) {
if (strlen($str) < 2) {
return $str;
}
$c0 = ord($str{0});
$c1 = ord($str{1});
$start = 0;
if ($c0 == 0xFE && $c1 == 0xFF) {
$be = true;
$start = 2;
} else if ($c0 == 0xFF && $c1 == 0xFE) {
$start = 2;
$be = false;
}
if ($be === null) {
$be = true;
}
$len = strlen($str);
$newstr = '';
for ($i = $start; $i < $len; $i += 2) {
if ($be) {
$val = ord($str{$i}) << 4;
$val += ord($str{$i+1});
} else {
$val = ord($str{$i+1}) << 4;
$val += ord($str{$i});
}
$newstr .= ($val == 0x228) ? "\n" : chr($val);
}
return $newstr;
}
?>
Trying the "setlocale" trick did not work for me, e.g.
<?php
setlocale(LC_CTYPE, "en.UTF16");
$line = fgetcsv($file, ...)
?>
但这可能是因为我的平台 不支持它。但是,fgetcsv 仅支持单个字符 分隔符等,并抱怨如果 你传入了UTF-16版本的说法 性格,所以我放弃了 快。
希望这对某人有帮助 那里。