2014-09-19 155 views
1

我在使用PHP讀取來自CSV文件的Unicode字符時遇到問題。使用PHP讀取UNICODE CSV

以下是UNICODE csv文件的截圖。

enter image description here

我使用的PHP代碼如下所示。

$delimiter = ","; 
$row = 1; 
$handle = fopen($filePath, "r"); 
while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) { 
    $num = count($data); 
    $row++; 
    for ($c=0; $c < $num; $c++) { 
    echo $data[$c]; 
    } 
} 
fclose($handle); 

對於上面的代碼,我在chrome瀏覽器中得到下面的輸出。它有垃圾人物。

enter image description here

但是,如果我在echo語句添加一個換行符作爲它下面給出正確的輸出。

echo $data[$c]."\n"; 

enter image description here

爲什麼它的行爲這樣的嗎?我不想追加這樣的換行符。

+0

它使我變得更糟。如果我將**「\ n」**更改爲**'\ n'**,則上述代碼本身不起作用。 ??它殺了我的頭。 – Malaiselvan 2014-09-19 19:22:01

回答

2

UNICODE CSV文件中的文本前添加以下。

Windows調用「Unicode」(誤導Unicode;不是編碼)的編碼實際上是UTF-16LE。這是每個代碼單元的兩字節編碼,所以ASCII字符出現爲ASCII字節後跟零字節。

PHP的fgetcsv函數不支持UTF-16 CSV,它只支持ASCII兼容的編碼。它在每個字節0x0A(換行符)和0x2C(逗號)上分開,但在UTF-16LE中換行符和逗號都是兩字節序列,分別是0x0A 0x00和0x2C 0x00。這意味着您將在每個字段的前面獲得前導單個0x00字節,但前一個字段會出現錯誤分割,而當值包含不是UTF-16編碼的換行符/逗號的一部分的0x0A或0x2C字​​節時。

當您將此輸出到UTF-16LE編碼輸出時,額外的0x00字節會將每個字段與最後一個字符排列成雙字節對齊,這意味着瀏覽器查看它會將交替字段看作不對齊並打印由一個字符的前導字節形成的無用字符與前一個字符的尾部字節。

因此,有兩種可能的事情可以做:

  • ,如果你必須在做任何選擇,避免UTF-16。因爲它不兼容ASCII,所以打破了許多期望的工具。一般來說,最好的編碼是UTF-8,它可以包含所有的字符,並仍然是一個ASCII超集...不幸的是,Excel拒絕直接以UTF-8保存CSV文件。

  • 使用某些可理解UTF-16的CSV解析器。無論如何,避免使用PHP的CSV函數是一個好主意,因爲它們與標準CSV不符(儘管存在標準......至少與RFC 4180和Excel生成的內容不符)是奇怪的事情。

0

嘗試顯示

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

$delimiter = ","; 
$row = 1; 
$handle = fopen($filePath, "r"); 
while (($data = fgetcsv($handle, 1000, $delimiter)) !== FALSE) { 
    $num = count($data); 
    $row++; 
    for ($c=0; $c < $num; $c++) { 
    echo $data[$c]; 
    } 
} 
fclose($handle); 
+0

不,還是一樣的問題。 – Malaiselvan 2014-09-19 19:18:09