今天主要是想写一个php导入csv文件的方法,其实网上一搜一大把。都是可以实现怎么去导入的。但是我导入的时候遇到了两个问题,一个是在windows上写代码的时候测试发生了乱码问题,然后解决了。第二个是提交到linux系统上的时候又发生了乱码。我开始还不清楚是乱码的原因,一开始我还以为是代码svn提交发生的错误,到最后我在我的一个群里提问了一下,一朋友是做phpcms的,他说他遇到从Windows提交到Linux的时候刚开始也总是发生错误,后来排查原因就是乱码导致成的。下面切入正题看怎么解决两个问题的吧!
问题一解决:
php读取csv文件,在windows上出现中文读取不到的情况,本人立马想到一个函数mb_convert_encoding();作如下设置 $str = mb_convert_encoding($str, "UTF-8", "GBK");然后就可以了。当然你也可以用iconv();作如下设置iconv(‘GBK',”UTF-8//TRANSLIT//IGNORE”,$str);这两个函数来解决在windows上面发生乱码的问题。
问题二解决:
php读取csv文件,在linux上出现中文读取不到的情况,百度,google后找到解决办法
就是添加了一行代码setlocale(LC_ALL, 'zh_CN');对,亮瞎你的眼了吧。就这么简单,如果你不知道,可能会花很多时间去解决这个问题。
PHP setlocale() 函数解释
定义和用法
setlocale() 函数设置地区信息(地域信息)。
地区信息是针对一个地理区域的语言、货币、时间以及其他信息。该函数返回当前的地区设置,若失败则返回 false。
以下是在资料上收集常用的地区标识:
复制代码 代码如下:
zh_CN GB2312
en_US.UTF-8 UTF-8
zh_TW BIG5
zh_HK BIG5-HKSCS
zh_TW.EUC-TW EUC-TW
zh_TW.UTF-8 UTF-8
zh_HK.UTF-8 UTF-8
zh_CN.GBK GBK
例如、
utf-8: setlocale(LC_ALL, ‘en_US.UTF-8′);
简体:setlocale(LC_ALL, ‘zh_CN');
之所以给大家讲 setlocale()这个函数,是因为我导入csv文件到linux系统的时候发生了乱码,包括用了mb_convert_encoding()和iconv()两个函数都是没搞定最后问题的。最后就加了这一句setlocale(LC_ALL, ‘zh_CN');加在导入csv文件开始的代码前面就轻松搞定了,然后我又找了一下资料,发现fgetcsv()函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误,所以我们需要对其进行区域性的设置。特分享给大家。
我还尝试用了以下代码也没能搞定,这些都是生成csv文件的header的设置。可能在我这里不起作用,但是在你那里也说不定哦。所以我都整理出来,尽可能的帮助遇到导入csv文件乱码的同行,因为在没办法的情况下真的太难处理了。大家可以都试试!总有一个是属于你的。
复制代码 代码如下:
<?php
$csvContent="csvzero,csvone,csvtwo,csvthree,csvfour,csvfive";
header("Content-Type: application/vnd.ms-excel; charset=GB2312");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=CSV数据.csv ");
header("Content-Transfer-Encoding: binary ");
$csvContent = iconv("utf-8","gb2312",$csvContent);
echo $csvContent;
exit;
?>
下面就再来具体看看php导入csv文件的代码:
两个函数简单介绍一下,
mb_detect_encoding()检测到的字符编码,或者无法检测指定字符串的编码时返回FALSE。
fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段。与fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式的字段,然后返回一个包含这些字段的数组。fgetcsv() 出错时返回 FALSE,包括碰到文件结束时。
注释:从 PHP 4.3.5 起,fgetcsv() 的操作是二进制安全的。
注释:CSV 文件中的空行将被返回为一个包含有单个 null 字段的数组,不会被当成错误。
注释:该函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误。
注释:如果碰到 PHP 在读取文件时不能识别 Macintosh 文件的行结束符,可以激活 auto_detect_line_endings 运行时配置选项。
复制代码 代码如下:
<?php
setlocale(LC_ALL, 'zh_CN'); //设置地区信息(地域信息)
$file = $_FILES['files'];
$file_type = substr(strstr($file['name'],'.'),1);
if ($file_type != 'csv'){
echo "<script type=\"text/javascript\">alert(\"文件格式错误,请重新上传!\"); </script>";
exit;
}
$handle = fopen($file['tmp_name'],"r");
$file_encoding = mb_detect_encoding($handle);
if ($file_encoding != 'ASCII'){
echo "<script type=\"text/javascript\">alert(\"文件编码错误,请重新上传!\"); </script>";
exit;
}
$row = 0;
$str="";
$sy="";
while ($data = fgetcsv($handle,1000,',')){
$row++;
if ($row == 0)
continue;
$num = count($data);
for ($i=0; $i<$num; $i++){
$str = (string)$data[$i].'|';
$str = mb_convert_encoding($str, "UTF-8", "GBK"); //已知源码为GBK,转换为utf-8
$sy .= $str; //我这里做的比较复杂,是用'|'将csv文件里面的内容用'|'全部拼起来,因为我导入的是商品信息,需要根据用户需
//要导入的数据去定义哪些数据是需要导入的。
}
}
if ($sy) { $sy = rtrim($sy, '|'); }
$arr = explode('|',$sy);
$key = array_slice($arr,0,$num); //这个数组就是csv文件里面标题,就是商品id,标题,卖点等等的数据
$skey = array();
$length = array();
$co = count($arr);
$p = $co/$num; //求出要取出的数据的长度
for($j=0;$j<$p;$j++){
$offset=($j-1)*$num; //偏移量,就像分页一样,我这里根据偏移量取出的一个数组就是一个商品的信息。
if($j==0){
$length[] = array_slice($arr,0,$num);
}else{
$length[] = array_slice($arr,$num+$offset,$num);//取出有哪些字段和商品
}
}
$arrtitle = array();
$arrfileds = array();
$arrtagname = DB::select('字段标识', '字段名称')->from('字段表')->fetch_all();
foreach ($arrtagname as $value) {
$arrfileds[$value['fileds_tags']] = $value['fileds_name'];
}
foreach ($fileds as $v)
{
$temarr= explode('-', $v);
if (isset($temarr[0]) && !empty($temarr[0])) {
if (isset($temarr[1]) && !empty($temarr[1])) {
if ($temarr[1] == 'wenben') {
$arrtitle[] = $arrfileds[$temarr[0]].'文本';
}
} else {
if ($temarr[0] != 'pic') { //是取出字段是图片就给去掉
$arrtitle[] = $arrfileds[$temarr[0]];
}
}
}
}
$skey = array();
$order = array();
$order[] = 'act_tag';
$order[] = 'channel_tag';
$order[] = 'created_time';
$order[] = 'orderby';
$rows ='';
$f = $co/$num;//求出有多少件商品
for($p=0;$p<count($arrtitle);$p++){
//这里就是根据自己的需求查出自己需要的数据,通过用户需要的商品字段标识查出表里相对应的英文标识。
$skey[]= DB::select('字段标识')->from('字段表')->where('字段名称', '=', $arrtitle[$p])->fetch_row();
$rows .= $skey[$p]['字段标识'].'|';
}
if($rows){ $rows = rtrim($rows,'|'); }
if(!empty($rows)){ $exrows = explode('|',$rows); }else{ $exrows = array(); }
$skeys = array_merge($order,$exrows);
$count1 = count($skeys); //字段的个数
if(!empty($length)){
for($x=1;$x<$f;$x++){ //求出有多少件商品就的循环多少次
$orders = array();
$orders[] = $act_tag;
$orders[] = $channel_tag;
$orders[] = time();
$newlen = array_merge($orders,$length[$x]);
if($count1 !== count($newlen)){ //如果商品字段的长度和商品的长度不等就证明用户有哪个字段没录入
$newrs = array();
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); </script>";
fclose($handle);
exit();
}else{ //start
$arrimport = array_combine($skeys,$newlen); //如果两个数组是相等的我就合并数组,并把导入csv里面的日期改为时间戳存储到数据库
if(!empty($arrimport['start_time'])){ $sta = strtotime($arrimport['start_time']); }else{ $sta=(int)0; }
if(!empty($arrimport['end_time'])){ $end = strtotime($arrimport['end_time']); }else{ $end=(int)0; }
$arrtime=array('start_time'=>$sta,'end_time'=>$end);
if(!empty($arrimport['start_time']) && !empty($arrimport['end_time'])){
$newrs=array_merge($arrimport,$arrtime);
}else{
$newrs = array();
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); </script>";
fclose($handle);
exit();
}
if(count($skeys) == count($newrs)){
DB::insert('商品表', array_values($skeys))
->values(array_values($newrs))
->execute();
}
} //end
}
}
if($row-1==(int)0){
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'您导入的商品为空!'."</font>"); </script>";
}else{
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'成功导入'."<font color=#f00;>".($row-1)."</font>".'件商品!'."</font>");
}
fclose($handle);
}
?>
以上是我工作需要所做的csv导入处理,可能和你的导入方式不同,但是部分代码总会对你有帮助!
以下是简单导入:
复制代码 代码如下:
<form enctype="multipart/form-data" action="import.php" method="POST">
导入模板
<label for="文件选择">文件选择:</label><input name="csv_goods" type="file" />
<input type="submit" value="导入" name="import" />
</form>
<?php
if (isset($_POST['import'])){
$file = $_FILES['csv_goods'];
$file_type = substr(strstr($file['name'],'.'),1);
// 检查文件格式
if ($file_type != 'csv'){
echo '文件格式不对,请重新上传!';
exit;
}
$handle = fopen($file['tmp_name'],"r");
$file_encoding = mb_detect_encoding($handle);
// 检查文件编码
if ($file_encoding != 'ASCII'){
echo '文件编码错误,请重新上传!';
exit;
}
$row = 0;
while ($data = fgetcsv($handle,1000,',')){
//echo "<font color=red>$row</font>"; //可以知道总共有多少行
$row++;
if ($row == 1)
continue;
$num = count($data);
// 这里会依次输出每行当中每个单元格的数据
for ($i=0; $i<$num; $i++){
echo $data[$i]."<br>";
// 在这里对数据进行处理
}
}
fclose($handle);
}
?>
问题一解决:
php读取csv文件,在windows上出现中文读取不到的情况,本人立马想到一个函数mb_convert_encoding();作如下设置 $str = mb_convert_encoding($str, "UTF-8", "GBK");然后就可以了。当然你也可以用iconv();作如下设置iconv(‘GBK',”UTF-8//TRANSLIT//IGNORE”,$str);这两个函数来解决在windows上面发生乱码的问题。
问题二解决:
php读取csv文件,在linux上出现中文读取不到的情况,百度,google后找到解决办法
就是添加了一行代码setlocale(LC_ALL, 'zh_CN');对,亮瞎你的眼了吧。就这么简单,如果你不知道,可能会花很多时间去解决这个问题。
PHP setlocale() 函数解释
定义和用法
setlocale() 函数设置地区信息(地域信息)。
地区信息是针对一个地理区域的语言、货币、时间以及其他信息。该函数返回当前的地区设置,若失败则返回 false。
以下是在资料上收集常用的地区标识:
复制代码 代码如下:
zh_CN GB2312
en_US.UTF-8 UTF-8
zh_TW BIG5
zh_HK BIG5-HKSCS
zh_TW.EUC-TW EUC-TW
zh_TW.UTF-8 UTF-8
zh_HK.UTF-8 UTF-8
zh_CN.GBK GBK
例如、
utf-8: setlocale(LC_ALL, ‘en_US.UTF-8′);
简体:setlocale(LC_ALL, ‘zh_CN');
之所以给大家讲 setlocale()这个函数,是因为我导入csv文件到linux系统的时候发生了乱码,包括用了mb_convert_encoding()和iconv()两个函数都是没搞定最后问题的。最后就加了这一句setlocale(LC_ALL, ‘zh_CN');加在导入csv文件开始的代码前面就轻松搞定了,然后我又找了一下资料,发现fgetcsv()函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误,所以我们需要对其进行区域性的设置。特分享给大家。
我还尝试用了以下代码也没能搞定,这些都是生成csv文件的header的设置。可能在我这里不起作用,但是在你那里也说不定哦。所以我都整理出来,尽可能的帮助遇到导入csv文件乱码的同行,因为在没办法的情况下真的太难处理了。大家可以都试试!总有一个是属于你的。
复制代码 代码如下:
<?php
$csvContent="csvzero,csvone,csvtwo,csvthree,csvfour,csvfive";
header("Content-Type: application/vnd.ms-excel; charset=GB2312");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Disposition: attachment;filename=CSV数据.csv ");
header("Content-Transfer-Encoding: binary ");
$csvContent = iconv("utf-8","gb2312",$csvContent);
echo $csvContent;
exit;
?>
下面就再来具体看看php导入csv文件的代码:
两个函数简单介绍一下,
mb_detect_encoding()检测到的字符编码,或者无法检测指定字符串的编码时返回FALSE。
fgetcsv() 函数从文件指针中读入一行并解析 CSV 字段。与fgets() 类似,不同的是 fgetcsv() 解析读入的行并找出 CSV 格式的字段,然后返回一个包含这些字段的数组。fgetcsv() 出错时返回 FALSE,包括碰到文件结束时。
注释:从 PHP 4.3.5 起,fgetcsv() 的操作是二进制安全的。
注释:CSV 文件中的空行将被返回为一个包含有单个 null 字段的数组,不会被当成错误。
注释:该函数对区域设置是敏感的。比如说 LANG 设为 en_US.UTF-8 的话,单字节编码的文件就会出现读取错误。
注释:如果碰到 PHP 在读取文件时不能识别 Macintosh 文件的行结束符,可以激活 auto_detect_line_endings 运行时配置选项。
复制代码 代码如下:
<?php
setlocale(LC_ALL, 'zh_CN'); //设置地区信息(地域信息)
$file = $_FILES['files'];
$file_type = substr(strstr($file['name'],'.'),1);
if ($file_type != 'csv'){
echo "<script type=\"text/javascript\">alert(\"文件格式错误,请重新上传!\"); </script>";
exit;
}
$handle = fopen($file['tmp_name'],"r");
$file_encoding = mb_detect_encoding($handle);
if ($file_encoding != 'ASCII'){
echo "<script type=\"text/javascript\">alert(\"文件编码错误,请重新上传!\"); </script>";
exit;
}
$row = 0;
$str="";
$sy="";
while ($data = fgetcsv($handle,1000,',')){
$row++;
if ($row == 0)
continue;
$num = count($data);
for ($i=0; $i<$num; $i++){
$str = (string)$data[$i].'|';
$str = mb_convert_encoding($str, "UTF-8", "GBK"); //已知源码为GBK,转换为utf-8
$sy .= $str; //我这里做的比较复杂,是用'|'将csv文件里面的内容用'|'全部拼起来,因为我导入的是商品信息,需要根据用户需
//要导入的数据去定义哪些数据是需要导入的。
}
}
if ($sy) { $sy = rtrim($sy, '|'); }
$arr = explode('|',$sy);
$key = array_slice($arr,0,$num); //这个数组就是csv文件里面标题,就是商品id,标题,卖点等等的数据
$skey = array();
$length = array();
$co = count($arr);
$p = $co/$num; //求出要取出的数据的长度
for($j=0;$j<$p;$j++){
$offset=($j-1)*$num; //偏移量,就像分页一样,我这里根据偏移量取出的一个数组就是一个商品的信息。
if($j==0){
$length[] = array_slice($arr,0,$num);
}else{
$length[] = array_slice($arr,$num+$offset,$num);//取出有哪些字段和商品
}
}
$arrtitle = array();
$arrfileds = array();
$arrtagname = DB::select('字段标识', '字段名称')->from('字段表')->fetch_all();
foreach ($arrtagname as $value) {
$arrfileds[$value['fileds_tags']] = $value['fileds_name'];
}
foreach ($fileds as $v)
{
$temarr= explode('-', $v);
if (isset($temarr[0]) && !empty($temarr[0])) {
if (isset($temarr[1]) && !empty($temarr[1])) {
if ($temarr[1] == 'wenben') {
$arrtitle[] = $arrfileds[$temarr[0]].'文本';
}
} else {
if ($temarr[0] != 'pic') { //是取出字段是图片就给去掉
$arrtitle[] = $arrfileds[$temarr[0]];
}
}
}
}
$skey = array();
$order = array();
$order[] = 'act_tag';
$order[] = 'channel_tag';
$order[] = 'created_time';
$order[] = 'orderby';
$rows ='';
$f = $co/$num;//求出有多少件商品
for($p=0;$p<count($arrtitle);$p++){
//这里就是根据自己的需求查出自己需要的数据,通过用户需要的商品字段标识查出表里相对应的英文标识。
$skey[]= DB::select('字段标识')->from('字段表')->where('字段名称', '=', $arrtitle[$p])->fetch_row();
$rows .= $skey[$p]['字段标识'].'|';
}
if($rows){ $rows = rtrim($rows,'|'); }
if(!empty($rows)){ $exrows = explode('|',$rows); }else{ $exrows = array(); }
$skeys = array_merge($order,$exrows);
$count1 = count($skeys); //字段的个数
if(!empty($length)){
for($x=1;$x<$f;$x++){ //求出有多少件商品就的循环多少次
$orders = array();
$orders[] = $act_tag;
$orders[] = $channel_tag;
$orders[] = time();
$newlen = array_merge($orders,$length[$x]);
if($count1 !== count($newlen)){ //如果商品字段的长度和商品的长度不等就证明用户有哪个字段没录入
$newrs = array();
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); </script>";
fclose($handle);
exit();
}else{ //start
$arrimport = array_combine($skeys,$newlen); //如果两个数组是相等的我就合并数组,并把导入csv里面的日期改为时间戳存储到数据库
if(!empty($arrimport['start_time'])){ $sta = strtotime($arrimport['start_time']); }else{ $sta=(int)0; }
if(!empty($arrimport['end_time'])){ $end = strtotime($arrimport['end_time']); }else{ $end=(int)0; }
$arrtime=array('start_time'=>$sta,'end_time'=>$end);
if(!empty($arrimport['start_time']) && !empty($arrimport['end_time'])){
$newrs=array_merge($arrimport,$arrtime);
}else{
$newrs = array();
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'请检查第,'.($x-1).'件商品!'.'导入失败!'."</font>"); </script>";
fclose($handle);
exit();
}
if(count($skeys) == count($newrs)){
DB::insert('商品表', array_values($skeys))
->values(array_values($newrs))
->execute();
}
} //end
}
}
if($row-1==(int)0){
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'您导入的商品为空!'."</font>"); </script>";
}else{
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'成功导入'."<font color=#f00;>".($row-1)."</font>".'件商品!'."</font>");
}
fclose($handle);
}
?>
以上是我工作需要所做的csv导入处理,可能和你的导入方式不同,但是部分代码总会对你有帮助!
以下是简单导入:
复制代码 代码如下:
<form enctype="multipart/form-data" action="import.php" method="POST">
导入模板
<label for="文件选择">文件选择:</label><input name="csv_goods" type="file" />
<input type="submit" value="导入" name="import" />
</form>
<?php
if (isset($_POST['import'])){
$file = $_FILES['csv_goods'];
$file_type = substr(strstr($file['name'],'.'),1);
// 检查文件格式
if ($file_type != 'csv'){
echo '文件格式不对,请重新上传!';
exit;
}
$handle = fopen($file['tmp_name'],"r");
$file_encoding = mb_detect_encoding($handle);
// 检查文件编码
if ($file_encoding != 'ASCII'){
echo '文件编码错误,请重新上传!';
exit;
}
$row = 0;
while ($data = fgetcsv($handle,1000,',')){
//echo "<font color=red>$row</font>"; //可以知道总共有多少行
$row++;
if ($row == 1)
continue;
$num = count($data);
// 这里会依次输出每行当中每个单元格的数据
for ($i=0; $i<$num; $i++){
echo $data[$i]."<br>";
// 在这里对数据进行处理
}
}
fclose($handle);
}
?>
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2024年11月26日
2024年11月26日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]