2012-01-16 237 views
22

文件我嘗試讀取一個CSV和回聲的內容。但內容顯示的字符錯誤。UTF-8的問題,而讀CSV與fgetcsv

MAXMüstermänn - >MäxMüstermänn

CSV文件的編碼是UTF-8無BOM(與記事本檢查++)。

這是CSV文件的內容:

"Mäx";"Müstermänn"

我的PHP腳本

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
</head> 
<body> 
<?php 
$handle = fopen ("specialchars.csv","r"); 
echo '<table border="1"><tr><td>First name</td><td>Last name</td></tr><tr>'; 
while ($data = fgetcsv ($handle, 1000, ";")) { 
     $num = count ($data); 
     for ($c=0; $c < $num; $c++) { 
      // output data 
      echo "<td>$data[$c]</td>"; 
     } 
     echo "</tr><tr>"; 
} 
?> 
</body> 
</html> 

我試圖用setlocale(LC_ALL, 'de_DE.utf8');的建議here沒有成功。內容仍顯示錯誤。

什麼我失蹤?

編輯:

echo mb_detect_encoding($data[$c],'UTF-8');給我UTF-8 UTF-8。

echo file_get_contents("specialchars.csv");給我"Mäx";"Müstermänn"

而且

print_r(str_getcsv(reset(explode("\n", file_get_contents("specialchars.csv"))), ';')) 

給我

Array ([0] => Mäx [1] => Müstermänn)

是什麼意思?

+0

當你這樣做的file_get_contents回聲( 「specialchars.csv」)會發生什麼?當你做print_r時會發生什麼(str_getcsv(reset(explode(「\ n」,file_get_contents(「specialchars.csv」))),';'))? – Furgas 2012-01-16 18:06:11

+0

我更新了我的問題! – testing 2012-01-17 13:02:38

回答

2

現在,我得到它的工作(除去header命令後)。我認爲問題是,PHP文件的編碼是ISO-8859-1。我將它設置爲沒有BOM的UTF-8。我以爲我已經做到了,但也許我做了一個額外的撤銷。

此外,我用SET NAMES 'utf8'數據庫。現在在數據庫中也是正確的。

+0

如果導入的文件是另一個字符集,而不是您的代碼,則可能還需要setlocale()。 – tim 2013-05-12 00:16:00

6

嘗試把這個變成你的文件的頂部(之前任何其他輸出):

<?php 

header('Content-Type: text/html; charset=UTF-8'); 

?> 
+1

如果我把它放在上面,我會得到 。 – testing 2012-01-17 12:55:08

+0

也許我應該提到,我通過enctype =「multipart/form-data」accept-charset =「utf-8」'的形式上傳了csv文件。如果我把你的代碼放到例子中,看起來好像工作起來。 – testing 2012-01-17 13:34:13

3

問題是該函數返回UTF-8(它可以使用mb_detect_encoding進行檢查),但不會轉換,並且這些字符采用UTF-8。 Тherefore,有必要做反向轉換爲初始使用iconv編碼(Windows的1251或CP1251)。但是,由於由fgetcsv返回一個數組,我建議編寫自定義功能: [對不起,我的英語]

function customfgetcsv(&$handle, $length, $separator = ';'){ 
    if (($buffer = fgets($handle, $length)) !== false) { 
     return explode($separator, iconv("CP1251", "UTF-8", $buffer)); 
    } 
    return false; 
} 
+0

在我的特殊情況下,這一個工作。 – Alliswell 2016-10-25 05:10:32

10

遇到了類似的問題是:解析CSV包含特殊字符,如:E,E,O等文件...

對我來說,以下的罰款:

要正確表示HTML頁面上的文字,需要頭:

header('Content-Type: text/html; charset=UTF-8'); 

爲了正確地分析每一個角色,我用:

utf8_encode(fgets($file)); 

不要忘記在所有以下字符串操作中使用'多字節字符串函數',如:

mb_strtolower($value, 'UTF-8'); 
+0

你剛剛爲我節省了很多時間,謝謝!我一直試圖解決這個問題很長一段時間.. – 2015-06-15 10:47:47

+0

謝謝,'utf8_encode'爲我做了詭計。 – Latheesan 2017-06-05 20:22:26

34

試試這個:

<?php 
$handle = fopen ("specialchars.csv","r"); 
echo '<table border="1"><tr><td>First name</td><td>Last name</td></tr><tr>'; 
while ($data = fgetcsv ($handle, 1000, ";")) { 
     $data = array_map("utf8_encode", $data); //added 
     $num = count ($data); 
     for ($c=0; $c < $num; $c++) { 
      // output data 
      echo "<td>$data[$c]</td>"; 
     } 
     echo "</tr><tr>"; 
} 
?> 
+0

這有所幫助。 – jayarjo 2015-04-27 07:30:56

+1

這完全刪除了與空間的特殊字符,這是完全危險的! – 2015-05-27 04:47:01

+0

這工作對我來說 – Edgar 2016-05-23 00:25:07

1

在我的情況下,源文件中有窗-1250編碼和iconv打印萬噸約在輸入字符串非法字符通知書......

所以這個解決方案在幫助我很多:

/** 
* getting CSV array with UTF-8 encoding 
* 
* @param resource &$handle 
* @param integer  $length 
* @param string  $separator 
* 
* @return array|false 
*/ 
private function fgetcsvUTF8(&$handle, $length, $separator = ';') 
{ 
    if (($buffer = fgets($handle, $length)) !== false) 
    { 
     $buffer = $this->autoUTF($buffer); 
     return str_getcsv($buffer, $separator); 
    } 
    return false; 
} 

/** 
* automatic convertion windows-1250 and iso-8859-2 info utf-8 string 
* 
* @param string $s 
* 
* @return string 
*/ 
private function autoUTF($s) 
{ 
    // detect UTF-8 
    if (preg_match('#[\x80-\x{1FF}\x{2000}-\x{3FFF}]#u', $s)) 
     return $s; 

    // detect WINDOWS-1250 
    if (preg_match('#[\x7F-\x9F\xBC]#', $s)) 
     return iconv('WINDOWS-1250', 'UTF-8', $s); 

    // assume ISO-8859-2 
    return iconv('ISO-8859-2', 'UTF-8', $s); 
} 

迴應@ manvel的答案 - 用str_getcsv而不是爆炸 - 因爲這樣的情況:

some;nice;value;"and;here;comes;combinated;value";and;some;others 

爆炸會發生爆炸串入部分:

some 
nice 
value 
"and 
here 
comes 
combinated 
value" 
and 
some 
others 

但str_getcsv會爆炸串入部分:

some 
nice 
value 
and;here;comes;combinated;value 
and 
some 
others