如何解决php导入csv文件碰到乱码的问题
这篇文章主要介绍了php导入csv文件碰到乱码问题的解决方法,需要的朋友可以参考下
今天主要是想写一个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中文网!
相关推荐:
php处理中文字符串截取(mb_substr)和获取中文字符串字数的介绍
以上是如何解决php导入csv文件碰到乱码的问题的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

word页码乱码的解决办法:1、打开word文档,点击左上角的“文件”选项;2、选择“更多”选项,再点击“选项”按钮;3、在word选项中选择“高级”;4、在“显示文档内容”中找到“显示域代码而非域值”,去掉前方的勾选,并点击确定,回到主页即可。

Linux中文乱码问题是使用中文字符集和编码时常见的一个问题。出现乱码的原因可能是文件编码设置不正确,系统语言环境未安装或未设置,以及终端显示配置错误等。本文将介绍几种常见的解决方法,并提供具体的代码示例。一、检查文件编码设置使用file命令查看文件编码在终端中使用file命令,可以查看文件的编码:file-ifilename如果输出中有"charset

tomcat启动乱码的解决办法:1、修改Tomcat的conf配置文件;2、修改系统语言;3、修改命令行窗口编码;4、检查Tomcat服务器配置;5、检查项目编码;6、检查日志文件;7、尝试其他解决方案。详细介绍:1、修改Tomcat的conf配置文件,打开Tomcat的conf目录,找到"logging.properties"文件等等。

在Windows10系统中,出现乱码现象可谓是司空见惯。这背后的原因往往在于该操作系统并未对部分字符集提供默认的支持,抑或是设定的字符集选项存在错误。为了对症下药,以下我们将为您详细解析实际的操作规程。windows10乱码怎么解决1、打开设置,找到“时间和语言”2、再找到“语言”3、找到“管理语言设置”4、点击这里的“更改系统区域设置”5、如图勾选上然后点击确定就可以了。

linux tty中文乱码的解决办法:1、通过“sudo apt-get install fbterm”命令下载字体fbterm;2、执行“sudo fbterm”命令;3、更改字体和字体大小为“font-names=Ubuntu Mono font-size=14”即可。

filezilla乱码的解决办法有:1、检查编码设置;2、检查文件本身;3、检查服务器配置;4、尝试其他传输工具;5、更新软件版本;6、检查网络问题;7、寻求技术支持。解决FileZilla乱码问题需要从多个方面入手,逐步排查问题原因,并采取相应的措施进行修复。

win11文本文档乱码怎么解决?很多用户在使用win11系统的时候出现了文本文档乱码的情况而导致无法正常的进行阅读,出现这个问题很多小伙伴都不知道该如何解决。其实这个方法并不难,下面小编整理了windows11系统文档乱码解决步骤,希望能够给大家带来一点启发!windows11系统文档乱码解决步骤1、首先,打开win11的控制面板,在下面的搜索框中输入控制面板,点击搜索,进入控制面板。2、进入面板后,找到时钟和区域并点击进入,再点击区域选项。3、进入后,点击管理面板,然后再点击更改系统区域设置。

有很多的用户们在使用电脑的时候,会发现有很多的文件的尾缀是dll,但是很多的用户们都不知道这种文件需要怎么打开,想要知道的用户们快来看看以下详细教程吧~dll文件怎么打开编辑:1、下载一个叫做“exescope”的软件,并下载安装。2、然后右键dll文件,选择“用exescope编辑资源”。3、然后在弹出的错误提示框中,点击“确定”。4、然后在右边的面板上,点击每个组前面的“+”号可以查看到它所包含的内容。5、点击需要查看的dll文件,就能够看到了,然后点击“文件”,选择“导出”。6、然后就能够
