php導入csv文件碰到亂碼問題的解決方法


問題一解決: 在windows上寫代碼的時候測試發生了亂碼問題

方法一:函數mb_convert_encoding();作如下設置 $str = mb_convert_encoding($str, "UTF-8", "GBK");然后就可以了。

方法二:函數iconv();作如下設置iconv(‘GBK',”UTF-8//TRANSLIT//IGNORE”,$str);

這兩個函數來解決在windows上面發生亂碼的問題。 

 

問題二解決: 提交到linux系統上的時候又發生了亂碼

php讀取csv文件,在linux上出現中文讀取不到的情況,解決辦法 
添加了一行代碼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'); 

 

fgetcsv()函數對區域設置是敏感的。比如說 LANG 設為 en_US.UTF-8 的話,單字節編碼的文件就會出現讀取錯誤,所以我們需要對其進行區域性的設置。特分享給大家。 

$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 運行時配置選項。 
  1 setlocale(LC_ALL, 'zh_CN'); //設置地區信息(地域信息) 
  2 $file = $_FILES['files']; 
  3 $file_type = substr(strstr($file['name'],'.'),1); 
  4 if ($file_type != 'csv'){ 
  5   echo "<script type=\"text/javascript\">alert(\"文件格式錯誤,請重新上傳!\"); </script>"; 
  6   exit; 
  7 }
8 $handle = fopen($file['tmp_name'],"r"); 9 $file_encoding = mb_detect_encoding($handle); 10 if ($file_encoding != 'ASCII'){ 11   echo "<script type=\"text/javascript\">alert(\"文件編碼錯誤,請重新上傳!\"); </script>"; 12   exit; 13 }
14 $row = 0; 15 $str=""; 16 $sy="";
17 while ($data = fgetcsv($handle,1000,',')){ 18   $row++; 19   if ($row == 0) 20     continue; 21   $num = count($data); 22   for ($i=0; $i<$num; $i++){ 23     $str = (string)$data[$i].'|'; 24     $str = mb_convert_encoding($str, "UTF-8", "GBK"); //已知源碼為GBK,轉換為utf-8 25     $sy .= $str; //我這里做的比較復雜,是用'|'將csv文件里面的內容用'|'全部拼起來,因為我導入的是商品信息,需要根據用戶需 26     //要導入的數據去定義哪些數據是需要導入的。 27   } 28 } 29 if ($sy) { $sy = rtrim($sy, '|'); } 30 $arr = explode('|',$sy); 31 $key = array_slice($arr,0,$num); //這個數組就是csv文件里面標題,就是商品id,標題,賣點等等的數據 32 $skey = array(); 33 $length = array(); 34 $co = count($arr); 35 $p = $co/$num; //求出要取出的數據的長度 36 for($j=0;$j<$p;$j++){ 37  $offset=($j-1)*$num; //偏移量,就像分頁一樣,我這里根據偏移量取出的一個數組就是一個商品的信息。 38  if($j==0){ 39    $length[] = array_slice($arr,0,$num); 40  }else{ 41    $length[] = array_slice($arr,$num+$offset,$num);//取出有哪些字段和商品 42  } 43 } 44 $arrtitle = array(); 45 $arrfileds = array(); 46 $arrtagname = DB::select('字段標識', '字段名稱')->from('字段表')->fetch_all(); 47 foreach ($arrtagname as $value) { 48   $arrfileds[$value['fileds_tags']] = $value['fileds_name']; 49 } 50 foreach ($fileds as $v) 51 { 52   $temarr= explode('-', $v); 53   if (isset($temarr[0]) && !empty($temarr[0])) { 54     if (isset($temarr[1]) && !empty($temarr[1])) { 55       if ($temarr[1] == 'wenben') { 56         $arrtitle[] = $arrfileds[$temarr[0]].'文本'; 57       } 58     } else { 59       if ($temarr[0] != 'pic') { //是取出字段是圖片就給去掉 60         $arrtitle[] = $arrfileds[$temarr[0]]; 61       } 62     } 63   } 65 } 66 67 $skey = array(); 68 $order = array(); 69 $order[] = 'act_tag'; 70 $order[] = 'channel_tag'; 71 $order[] = 'created_time'; 72 $order[] = 'orderby'; 73 $rows =''; 74 $f = $co/$num;//求出有多少件商品 75 for($p=0;$p<count($arrtitle);$p++){ 76   //這里就是根據自己的需求查出自己需要的數據,通過用戶需要的商品字段標識查出表里相對應的英文標識。 77   $skey[]= DB::select('字段標識')->from('字段表')->where('字段名稱', '=', $arrtitle[$p])->fetch_row(); 78   $rows .= $skey[$p]['字段標識'].'|'; 79 } 80 if($rows){ $rows = rtrim($rows,'|'); } 81 if(!empty($rows)){ $exrows = explode('|',$rows); }else{ $exrows = array(); } 82 $skeys = array_merge($order,$exrows); 83 $count1 = count($skeys); //字段的個數 84 if(!empty($length)){ 85 for($x=1;$x<$f;$x++){ //求出有多少件商品就的循環多少次 86   $orders = array(); 87   $orders[] = $act_tag; 88   $orders[] = $channel_tag; 89   $orders[] = time(); 90   $newlen = array_merge($orders,$length[$x]); 91   if($count1 !== count($newlen)){ //如果商品字段的長度和商品的長度不等就證明用戶有哪個字段沒錄入 92     $newrs = array(); 93     echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'請檢查第,'.($x-1).'件商品!'.'導入失敗!'."</font>"); </script>"; 94     fclose($handle); 95     exit(); 96   }else{ //start 97     $arrimport = array_combine($skeys,$newlen); //如果兩個數組是相等的我就合並數組,並把導入csv里面的日期改為時間戳存儲到數據庫 98     if(!empty($arrimport['start_time'])){ $sta = strtotime($arrimport['start_time']); }else{ $sta=(int)0; } 99     if(!empty($arrimport['end_time'])){ $end = strtotime($arrimport['end_time']); }else{ $end=(int)0; } 100     $arrtime=array('start_time'=>$sta,'end_time'=>$end); 101     if(!empty($arrimport['start_time']) && !empty($arrimport['end_time'])){ 102     $newrs=array_merge($arrimport,$arrtime); 103   }else{ 104     $newrs = array(); 105     echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'請檢查第,'.($x-1).'件商品!'.'導入失敗!'."</font>"); </script>"; 106     fclose($handle); 107     exit(); 108   } 109   if(count($skeys) == count($newrs)){ 110     DB::insert('商品表', array_values($skeys)) 111       ->values(array_values($newrs)) 112       ->execute(); 113   } 114 } //end 115 } 116 } 117 if($row-1==(int)0){ 118   echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'您導入的商品為空!'."</font>"); </script>"; 119 }else{ 120 echo "<script type=\"text/javascript\">alert(\"<font color=#f00;>".'成功導入'."<font color=#f00;>".($row-1)."</font>".'件商品!'."</font>"); 121 } 122 fclose($handle); 123 }

以下是簡單導入:

 1 <form enctype="multipart/form-data" action="import.php" method="POST"> 
 2 導入模板 
 3 <label for="文件選擇">文件選擇:</label><input name="csv_goods" type="file" /> 
 4 <input type="submit" value="導入" name="import" /> 
 5 </form> 
 6 
 7 
 8 <?php 
 9 if (isset($_POST['import'])){ 
10     $file = $_FILES['csv_goods']; 
11     $file_type = substr(strstr($file['name'],'.'),1); 
12 
13     // 檢查文件格式 
14     if ($file_type != 'csv'){ 
15         echo '文件格式不對,請重新上傳!'; 
16         exit; 
17     } 
18     $handle = fopen($file['tmp_name'],"r"); 
19     $file_encoding = mb_detect_encoding($handle); 
20 
21     // 檢查文件編碼 
22     if ($file_encoding != 'ASCII'){ 
23         echo '文件編碼錯誤,請重新上傳!'; 
24         exit; 
25     } 
26 
27     $row = 0; 
28     while ($data = fgetcsv($handle,1000,',')){ 
29         //echo "<font color=red>$row</font>"; //可以知道總共有多少行 
30         $row++; 
31         if ($row == 1) 
32             continue; 
33             
34         $num = count($data); 
35         // 這里會依次輸出每行當中每個單元格的數據 
36         for ($i=0; $i<$num; $i++){ 
37             echo $data[$i]."<br>"; 
38             // 在這里對數據進行處理 
39         } 
40     } 
41     fclose($handle); 
42 } 
43 ?>

地址:

http://www.jb51.net/article/46609.htm

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM