2009-11-24 31 views
3

我有很大的問題,這個解決一個:UTF-8,PHP和XML Mysql的

我有一個MySQL數據庫編碼latin1_swedish_ci和存儲姓名和地址的表。

我試圖輸出UTF-8的XML文件,但我有以下字符串的問題:

Otivägen當我使用VIM文件,它被輸出爲Otivägen。此外,當它打開IE瀏覽器,我得到

An invalid character was found in text content. Error processing resource

我有以下代碼:

function fixEncoding($in_str) 
{ 
    $cur_encoding = mb_detect_encoding($in_str) ; 
    if($cur_encoding == "UTF-8" && mb_check_encoding($in_str,"UTF-8")) 
     return $in_str; 
    else 
     return utf8_encode($in_str); 
} 

header("Content-type: text/plain;charset=utf-8"); 
$mystring = "Otivägen" // this is actually obtained from database; 

$myxml = "<myxml> 
.... 
    <node>".$mystring."</node> 
.... 
</myxml> 
"; 
$myxml = fixEncoding($myxml); 

實際的XML輸出低於:

<?xml version="1.0" encoding="UTF-8" ?> 
<myxml> 
    .... 
    <node>Otivägen</node> 
    .... 
</myxml> 

任何想法如何,我可以輸出文件,所以在vim文件讀取Otivägen而不是Otivägen

編輯:

我做mysql_client_encoding(),並得到latin1
然後我做了mysql_set_charset()
並再次運行mysql_client_encoding(),得到了UTF8,但仍然是相同的輸出問題。

編輯2

我已經登錄到命令行,並提前運行查詢SELECT address1 FROM address WHERE id = 1000;

SELECT address1 FROM address WHERE id = 1000; 
Current database: ftpuser_db 

+-------------+ 
| address1 | 
+-------------+ 
| Otivägen 32 | 
+-------------+ 
1 row in set (0.06 sec) 

謝謝!

回答

1

我認爲你做的一切都是正確的,只是你的終端是在拉丁語-1。

ä的UTF-8序列是C3 A4,如果顯示爲Latin-1,則爲ΔA4。

2

您的MySQL連接編碼是否正確設置爲UTF-8

查看mysql_set_charset()mysql_client_encoding()瞭解更多詳情。

+0

我做了mysql_client_encoding()並得到了latin1,然後我做了mysql_set_charset(),然後再次運行mysql_client_encoding()並獲得了utf8,但仍然是同樣的問題。 – Lizard

+0

您是否曾嘗試在每個'$ myString'上分別應用'fixEncoding()',而不是在整個'$ myXml'上應用一次? – Wookai

+0

是我試過'$ mystring'但是這並沒有改變任何東西 – Lizard

0

latin1_swedish_ci是整理,而不是字符集。由於排序規則應該與它們的字符集匹配,因此它建議該表使用latin1,但這不是保證。

嚴格來說,表格的字符集在這裏並不重要,因爲MySql可以轉換輸入/輸出。這就是連接字符集(mysql_set_charset)的用途。但是,爲了正常工作,數據需要在數據庫中正確編碼。我首先檢查字符串在數據庫中是否正確。最簡單的方法是登錄命令行並選擇一個非ASCII字符的行。它看起來好嗎?

$mystring = "Otivägen" // this is actually obtained from database; 

小心。 $mystring中的數據編碼現在將取決於php文件的編碼。這可能與數據庫中的數據相同也可能不同。

+0

我已經登錄到命令行並運行查詢'SELECT ad_address1 FROM address WHERE id = 1000;並按預期輸出。那麼我現在應該尋找什麼? – Lizard

0

輸出運行查詢之前SET NAMES utf8

輸出,你可以回去和運行SET NAMES latin1

here,我已經得到了同樣的問題

+0

對不起,這也沒有工作:(沒有差異輸出。 – Lizard

0

看來你是「雙重編碼」Otivägen後。如果Otivägen已經是UTF-8,並且再次運行utf8_encode(),你會得到這種行爲。例如:

$str = "Otivägen"; // already an UTF-8 string 
echo utf8_encode($str); // outputs Otivägen 

我不知道我們是真正的「雙重編碼」的發生,但它可能是由於你的編輯器設置。我的理論。假設您正在運行Aptana Studio:您的實際字符集已設置爲ISO-8859-1(在Aptana中,您可以通過右鍵單擊文件並選擇「屬性」來檢查此項。要爲所有項目設置默認字符編碼,請選擇從Aptana主菜單 - >常規 - >工作區)的首選項。如果是這種情況,那麼您檢測到的實際PHP源文件$myxml及其字符串<myxml><node>...被檢測爲ISO-8859-1,但從數據庫收到的$ mystring爲UTF-8。然後,您的fixEncoding函數將運行else子句,因爲$ myxml作爲一個整體被視爲ISO-8859-1而不是UTF-8。這會導致對數據庫結果進行雙重編碼,並可能導致您的問題。

檢查編輯器中實際源文件的編碼,並驗證它是否設置爲UTF-8。或者,嘗試將fixEncoding/utf8_encode/utf8_decode應用或刪除到$ myxml。觀察結果並查看需要對Otivatgen的價值做些什麼。

+0

酷感謝您將嘗試此 – Lizard

2

哦,男孩。 UTF8問題可能是一個真正的痛苦,當某些事情正在爲你重新編碼時,它們幾乎不可能解決。

您確實需要從一端開始,並確保每個進程都是UTF8。這將消除解釋數據過程中的錯誤,併爲您「轉換」它。但重要的是,它還會讓你更容易地發現什麼時候某些東西已經錯誤地編碼了文本(是的,我遇到了這個問題)。

如果表中沒有設置爲UTF8並且可能會被錯誤編碼的UTF8數據,則需要在數據重新編碼之後最後執行表格。否則,您將無法挽回地損壞您的數據。我也有這個問題。

第一步:

  • 檢查你的終端是UTF8兼容。侏儒終端是。 Kterm是。 ETerm不是。
  • 檢查你的shell中的LANG設置。它應該具有.UTF-8的價值。
  • 檢查vim是否正確地選擇了UTF8設置。你可以用:set encoding

這將意味着你的文件將以UTF8編輯。

現在我們檢查MySQL。

在MySQL CLI中,執行show variables like 'character_set%';。結果可能會是這樣的:

+--------------------------+----------------------------+ 
| Variable_name   | Value      | 
+--------------------------+----------------------------+ 
| character_set_client  | latin1      | 
| character_set_connection | latin1      | 
| character_set_database | latin1      | 
| character_set_filesystem | binary      | 
| character_set_results | latin1      | 
| character_set_server  | latin1      | 
| character_set_system  | utf8      | 
| character_sets_dir  | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+ 

什麼你的目標是爲所有這些latin1值(或任何你所看到的)更改爲utf8

set names utf8;將改變他們中的大多數,你可能需要用數據庫中的每個新連接來做到這一點。這是我在之前的應用程序中必須採用的解決方案。其他要更改的設置位於my.cnf文件中,我需要將其指向the documentation。這是不太可能的,你將需要全部設置它們。

我看到你已經設置了輸出頭,所以這很好。

現在您可以查看數據庫中的數據,看看它爲什麼是「錯誤的」。