溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

php導(dǎo)入csv文件碰到亂碼問題如何解決

發(fā)布時間:2021-07-26 13:39:25 來源:億速云 閱讀:128 作者:chen 欄目:開發(fā)技術(shù)

這篇文章主要講解了“php導(dǎo)入csv文件碰到亂碼問題如何解決”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“php導(dǎo)入csv文件碰到亂碼問題如何解決”吧!

今天主要是想寫一個php導(dǎo)入csv文件的方法,其實(shí)網(wǎng)上一搜一大把。都是可以實(shí)現(xiàn)怎么去導(dǎo)入的。但是我導(dǎo)入的時候遇到了兩個問題,一個是在windows上寫代碼的時候測試發(fā)生了亂碼問題,然后解決了。第二個是提交到linux系統(tǒng)上的時候又發(fā)生了亂碼。我開始還不清楚是亂碼的原因,一開始我還以為是代碼svn提交發(fā)生的錯誤,到最后我在我的一個群里提問了一下,一朋友是做phpcms的,他說他遇到從Windows提交到Linux的時候剛開始也總是發(fā)生錯誤,后來排查原因就是亂碼導(dǎo)致成的。下面切入正題看怎么解決兩個問題的吧!

問題一解決:

php讀取csv文件,在windows上出現(xiàn)中文讀取不到的情況,本人立馬想到一個函數(shù)mb_convert_encoding();作如下設(shè)置 $str = mb_convert_encoding($str, "UTF-8", "GBK");然后就可以了。當(dāng)然你也可以用iconv();作如下設(shè)置iconv(‘GBK',”UTF-8//TRANSLIT//IGNORE”,$str);這兩個函數(shù)來解決在windows上面發(fā)生亂碼的問題。

問題二解決:

php讀取csv文件,在linux上出現(xiàn)中文讀取不到的情況,百度,google后找到解決辦法

就是添加了一行代碼setlocale(LC_ALL, 'zh_CN');對,亮瞎你的眼了吧。就這么簡單,如果你不知道,可能會花很多時間去解決這個問題。
PHP setlocale() 函數(shù)解釋
定義和用法

setlocale() 函數(shù)設(shè)置地區(qū)信息(地域信息)。

地區(qū)信息是針對一個地理區(qū)域的語言、貨幣、時間以及其他信息。該函數(shù)返回當(dāng)前的地區(qū)設(shè)置,若失敗則返回 false。
以下是在資料上收集常用的地區(qū)標(biāo)識:

復(fù)制代碼 代碼如下:


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()這個函數(shù),是因?yàn)槲覍?dǎo)入csv文件到linux系統(tǒng)的時候發(fā)生了亂碼,包括用了mb_convert_encoding()和iconv()兩個函數(shù)都是沒搞定最后問題的。最后就加了這一句setlocale(LC_ALL, ‘zh_CN');加在導(dǎo)入csv文件開始的代碼前面就輕松搞定了,然后我又找了一下資料,發(fā)現(xiàn)fgetcsv()函數(shù)對區(qū)域設(shè)置是敏感的。比如說 LANG 設(shè)為 en_US.UTF-8 的話,單字節(jié)編碼的文件就會出現(xiàn)讀取錯誤,所以我們需要對其進(jìn)行區(qū)域性的設(shè)置。特分享給大家。

我還嘗試用了以下代碼也沒能搞定,這些都是生成csv文件的header的設(shè)置??赡茉谖疫@里不起作用,但是在你那里也說不定哦。所以我都整理出來,盡可能的幫助遇到導(dǎo)入csv文件亂碼的同行,因?yàn)樵跊]辦法的情況下真的太難處理了。大家可以都試試!總有一個是屬于你的。

復(fù)制代碼 代碼如下:


<?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數(shù)據(jù).csv ");
header("Content-Transfer-Encoding: binary ");
$csvContent = iconv("utf-8","gb2312",$csvContent);
echo $csvContent;
exit;
?>


下面就再來具體看看php導(dǎo)入csv文件的代碼:

兩個函數(shù)簡單介紹一下,

mb_detect_encoding()檢測到的字符編碼,或者無法檢測指定字符串的編碼時返回FALSE。

fgetcsv() 函數(shù)從文件指針中讀入一行并解析 CSV 字段。與fgets() 類似,不同的是 fgetcsv() 解析讀入的行并找出 CSV 格式的字段,然后返回一個包含這些字段的數(shù)組。fgetcsv() 出錯時返回 FALSE,包括碰到文件結(jié)束時。

注釋:從 PHP 4.3.5 起,fgetcsv() 的操作是二進(jìn)制安全的。

注釋:CSV 文件中的空行將被返回為一個包含有單個 null 字段的數(shù)組,不會被當(dāng)成錯誤。

注釋:該函數(shù)對區(qū)域設(shè)置是敏感的。比如說 LANG 設(shè)為 en_US.UTF-8 的話,單字節(jié)編碼的文件就會出現(xiàn)讀取錯誤。

注釋:如果碰到 PHP 在讀取文件時不能識別 Macintosh 文件的行結(jié)束符,可以激活 auto_detect_line_endings 運(yùn)行時配置選項(xiàng)。

復(fù)制代碼 代碼如下:


<?php
setlocale(LC_ALL, 'zh_CN'); //設(shè)置地區(qū)信息(地域信息)
$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,轉(zhuǎn)換為utf-8
$sy .= $str; //我這里做的比較復(fù)雜,是用'|'將csv文件里面的內(nèi)容用'|'全部拼起來,因?yàn)槲覍?dǎo)入的是商品信息,需要根據(jù)用戶需
//要導(dǎo)入的數(shù)據(jù)去定義哪些數(shù)據(jù)是需要導(dǎo)入的。
}
}
if ($sy) { $sy = rtrim($sy, '|'); }
$arr = explode('|',$sy);
$key = array_slice($arr,0,$num); //這個數(shù)組就是csv文件里面標(biāo)題,就是商品id,標(biāo)題,賣點(diǎn)等等的數(shù)據(jù)
$skey = array();
$length = array();
$co = count($arr);
$p = $co/$num; //求出要取出的數(shù)據(jù)的長度
for($j=0;$j<$p;$j++){
$offset=($j-1)*$num; //偏移量,就像分頁一樣,我這里根據(jù)偏移量取出的一個數(shù)組就是一個商品的信息。
if($j==0){
$length[] = array_slice($arr,0,$num);
}else{
$length[] = array_slice($arr,$num+$offset,$num);//取出有哪些字段和商品
}
}
$arrtitle = array();
$arrfileds = array();
$arrtagname = DB::select('字段標(biāo)識', '字段名稱')->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++){
//這里就是根據(jù)自己的需求查出自己需要的數(shù)據(jù),通過用戶需要的商品字段標(biāo)識查出表里相對應(yīng)的英文標(biāo)識。
$skey[]= DB::select('字段標(biāo)識')->from('字段表')->where('字段名稱', '=', $arrtitle[$p])->fetch_row();
$rows .= $skey[$p]['字段標(biāo)識'].'|';
}
if($rows){ $rows = rtrim($rows,'|'); }
if(!empty($rows)){ $exrows = explode('|',$rows); }else{ $exrows = array(); }
$skeys = array_merge($order,$exrows);
$count1 = count($skeys); //字段的個數(shù)
if(!empty($length)){
for($x=1;$x<$f;$x++){ //求出有多少件商品就的循環(huán)多少次
$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).'件商品!'.'導(dǎo)入失敗!'."</font>"); </script>";
fclose($handle);
exit();
}else{ //start
$arrimport = array_combine($skeys,$newlen); //如果兩個數(shù)組是相等的我就合并數(shù)組,并把導(dǎo)入csv里面的日期改為時間戳存儲到數(shù)據(jù)庫
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).'件商品!'.'導(dǎo)入失??!'."</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;>".'您導(dǎo)入的商品為空!'."</font>"); </script>";
}else{
echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'成功導(dǎo)入'."<font color=#f00;>".($row-1)."</font>".'件商品!'."</font>");
}
fclose($handle);
}
?>


以上是我工作需要所做的csv導(dǎo)入處理,可能和你的導(dǎo)入方式不同,但是部分代碼總會對你有幫助!
以下是簡單導(dǎo)入:

復(fù)制代碼 代碼如下:


<form enctype="multipart/form-data" action="import.php" method="POST">
導(dǎo)入模板
<label for="文件選擇">文件選擇:</label><input name="csv_goods" type="file" />
<input type="submit" value="導(dǎo)入" 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);
// 這里會依次輸出每行當(dāng)中每個單元格的數(shù)據(jù)
for ($i=0; $i<$num; $i++){
echo $data[$i]."<br>";
// 在這里對數(shù)據(jù)進(jìn)行處理
}
}

fclose($handle);
}

?>

感謝各位的閱讀,以上就是“php導(dǎo)入csv文件碰到亂碼問題如何解決”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對php導(dǎo)入csv文件碰到亂碼問題如何解決這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI