在导入导出数据的时候常用的方法是:
让初始导入数据组织成csv格式.去除掉"," .然后读取合并导入
``
$fp = fopen(file);
while($data = fgetcsv($fp)){
$res[] = $data;
}
return $data;
fgetcsv方法在手册上面的解释是:
说明
array fgetcsv ( resource $handle [, int $length = 0 [, string $delimiter = ',' [, string $enclosure = '"' [, string $escape = '\' ]]]] )
和 fgets() 类似,只除了 fgetcsv() 解析读入的行并找出 CSV 格式的字段然后返回一个包含这些字段的数组。
在导入导出的过程中遇到了如下的问题:
CSV使用的编码格式是UTF8,并且里面存在中文.
解析出来的数组中,中文字符串出现表示不完全的问题.
原始数据是:
荔湾区西华路太保直街1号
但是通过函数处理后得到的结果是:
1号
非常奇葩的返回,如果是中文字符串乱码倒也还好解释,你为什么把我好端端的中文搞丢了
并且在测试环境和线上环境出现了表现不一致的问题. 测试环境是好用的OK的.但是线上的正式环境就会出现这样奇葩的问题.
经过仔细排查发现我线上使用的PHP是 5.2.8 而测试环境使用的PHP版本是 5.4.17
最后找到是这个函数在作怪.但是具体哪里出现的不一致问题.还没办法确定.
在手册上找到如下说明:
Note:
该函数对区域设置是敏感的。比如说 LANG
设为 en_US.UTF-8
的话,单字节编码的文件就会出现读取错误。
这里前半句是重点.也就是说你的lang设置会影响到这个函数的行为.因为不想去down源码,以黑盒的角度来研究这个问题.
查看两台机器的lang配置
echo $LANG
线上显示 en_us
而测试环境显示 en_us.UTF-8
那么en_us
和en_us.utf-8
的区别应该是导致这个问题的罪魁祸首 .
网上找到这个问答:觉得说的有一定道理
https://serverfault.com/questions/605776/linux-locale-en-us-utf-8-vs-en-us
en_us
使用的字符集是 : ISO8859-1 而 en_us.utf-8
使用的字符集是UTF-8
黑盒猜想
网上查了查资料 其实 ISO的这个编码根本支持不了中文汉字.但是从计算机的角度出发,不管你传过来是啥,我都按照我的规则去编码就是了.于是编完了返回给PHP ,PHP 不认识,就挑认识的处理.
数字是能够正常编码的 , 前面的汉字就没办法了.于是从数字开始,编码回复正常.后面只剩下一个字,而且这个字是双字节的,从函数返回上来讲应该是当做两个字来传的,但是PHP一处理一 拼接就变成了一个字(字符的编码在两个编码表中都要存在.)
既然如此,那么解决办法也就有了 .我需要尝试吧线上的机器lang设置成utf-8 或者摒弃这个函数,用个别的函数来实现这个功能.
线上机器不敢动,不确定是不是会有别影响.于是改动了代码.最终实现 fgets($line);并且使用explode来实现了解析的功能.
另外在手册中没有体现5.4和5.2之间是否有差异.也就是说这个和PHP的版本关系并不大.应该就是语言的问题.