2011-06-22 19 views
1

我正在爲我正在處理的網站的管理部分構建數據導入工具。數據有法文和英文,並且包含許多重音字符。每當我嘗試上傳文件,解析數據並將其存儲在我的MySQL數據庫中時,重音都被替換爲'?'。上傳文件中的口音被替換爲'?'

我有文本文件包含數據(字符集是iso-8859-1),我上傳到我的服務器使用CodeIgniter的文件上傳庫。然後我用PHP讀取文件。

我的代碼是與此類似:

$this->upload->do_upload() 
$data = array('upload_data' => $this->upload->data()); 

$fileHandle = fopen($data['upload_data']['full_path'], "r"); 

while (($line = fgets($fileHandle)) !== false) { 
    echo $line; 
} 

這將產生與更換口音線 '?'。其他一切都是正確的。

如果我通過FTP從我的服務器上下載我上傳的文件,charset仍然是iso-8850-1,但差異顯示文件已更改。但是,如果我在TextEdit中打開文件,它會正確顯示。

我試圖使用PHP的stream_encoding方法明確地將我的文件流設置爲iso-8859-1,但我的PHP版本沒有該方法。

在想法用完之後,我試着在utf8_encodeutf8_decode中包裝我的字符串。都沒有工作。

如果有人對我可以嘗試的事情有什麼建議,我會非常感激。

回答

4

重要的是要查看是否腐敗發生之前或之後發出查詢發送到MySQL。這裏發生了太多可能的事情,無法找到它。你能輸出你的MySql來檢查嗎?

假設您的查詢已正確形成(在查詢輸出階段沒有損壞),您應該檢查幾件事情。

  1. 什麼是數據庫本身的字符編碼? (整理)

  2. 有什麼聯繫的字符集 - 這可能無法正確在你的MySQL配置設置,並且可以使用「組名稱」命令

在我自己的應用程序進行手動設置由於我無法更改MySQL配置,所以在建立連接後我發出'SET NAMES utf8'作爲我的第一個查詢。

看到這個。 http://dev.mysql.com/doc/refman/5.0/en/charset-connection.html

編輯:如果該問題不涉及到MySQL我會檢查以下內容

  1. 你說該文件的編碼是「字符集是ISO-8859-1」 - 可我問你如何確定這一點?

  2. 如果將文件本身保存爲utf8(沒有BOM)並嘗試重新處理它,會發生什麼情況?

  3. 正在執行轉換的文件的php的編碼是什麼? (你用什麼來寫你的PHP - 它可能是'管理'這個給你一個不希望的方式)

  4. (旁)是你正在處理的文件適合使用fgetcsv來處理? http://php.net/manual/en/function.fgetcsv.php

+0

如果我通過fgets()直接回顯正在讀入的字符串,它們會有問號而不是重音。我不認爲這個問題與MySQL有關。 – Katfish

+0

@Katfish請參閱編輯 – calumbrodie

+0

我在命令行中使用'file -I '檢查了文件的字符集。我使用Eclipse創建和編輯PHP文件,並將它們編碼爲ascii。我正在使用Filezilla上傳文件,但編碼似乎通過這種方式得以保留 - 當我下載以前上傳的文件時,它們仍然具有原始的字符集。 – Katfish

0

問題是您使用iso-8859-1而不是utf-8。爲了對其進行編碼,在正確的字符集,你應該使用的iconv功能,像這樣:

$output_string = iconv('utf-8", "utf-8//TRANSLIT", $input_string);

ISO-8859-1不具有任何形式口音的編碼。

如果所有東西都是utf-8,它會好得多,因爲它處理幾乎所有人都知道的字符。

+0

我剛剛嘗試使用iconv(),但它失敗了,錯誤'檢測到輸入字符串中的非法字符'。我也嘗試使用iso-8859-1作爲輸入字符集。如果iso-8859-1沒有任何重音編碼,它將如何顯示重音符號?像TextEdit這樣的程序在顯示之前會自動轉換編碼嗎? – Katfish

+1

@Katfish:IIRC iso-8859-1涵蓋法國口音。如果您將文件存儲到數據庫中,則應將它們存儲爲BLOB並按照「本機」編碼原樣傳送它們。在將它們存儲在數據庫中之前,請不要按照此答案中的建議對其進行修改。按原樣存儲它們。 – hakre

+0

@hakre我只存儲從我的數據庫中的文件中讀取的字符串。解析後文件被刪除。 – Katfish

1

文件上傳到服務器後應該返回上下載相同。這意味着,文件的編碼(這只是一堆二進制數據)不應該改變。相反,您應該注意,您可以不改變地存儲該文件的二進制信息。

爲了實現這一目標,請創建一個BLOB字段。這是正確的列類型。這只是二進制數據。

假設你使用MySQL,這是參考:The BLOB and TEXT Types,注意BLOB。

+0

我沒有存儲在我的數據庫中的文件;只是我從文件中讀取的字符串。 – Katfish

+0

數據庫中字段的數據類型是什麼? – hakre

+0

數據庫中的字段是文本,但在將任何內容存儲到數據庫之前,我已經失去了我的口音。如果我在從文件中讀取字符串時迴應字符串,則它們沒有重音符號。 – Katfish

相關問題