2016-04-19 46 views
1

我很努力地理解PHP中的字符編碼。瞭解PHP中的字符編碼

請看下面的代碼(可以運行它here):

$string = "\xe2\x82\xac"; 

var_dump(mb_internal_encoding()); 
var_dump($string); 
var_dump(unpack('C*', $string)); 
$utf8string = mb_convert_encoding($string, "UTF-8"); 
var_dump($utf8string); 
var_dump(unpack('C*', $utf8string)); 

mb_internal_encoding("UTF-8"); 

var_dump($string); 
var_dump($utf8string); 

我有一個字符串,實際上€字符,其Unicode代碼點來表示。到PHP 5.5使用的內部編碼是ISO-8859-1,因此我認爲我的字符串將使用此編碼進行編碼。用unpack我可以看到我的字符串的咬合表示,它對應於我用來定義字符串的十六進制代碼。

然後我將字符串的編碼轉換爲UTF-8,使用mb_convert_encoding。此時,字符串在屏幕上以不同的方式顯示,並且其字節表示發生變化(這是預期的)。

如果我更改PHP內部編碼也UTF-8,我期望utf8string正確顯示在屏幕上,但這不會發生。

我缺少什麼?

+1

正在瀏覽器中運行此操作嗎?這將自己選擇字符編碼,你最好脫離實體逃離違規角色。 – Chris

+0

向''添加''以確保瀏覽器也期待UTF8 – RiggsFolly

+0

PHP中的所有字符串都被視爲二進制字符串,'mb_internal_encoding()'幾乎不影響其他字符而不是其他'mb_ *'函數的工作方式。您也無法在同一個文檔中同時輸出ISO-8859和UTF8,並且期望無論什麼程序正在生成輸出,任何事情都會發生。 – Sammitch

回答

2

您顯示的腳本不使用任何非ASCII字符,因此其內部編碼沒有任何區別。 mb_internal_encoding會將您的數據轉換爲輸出。 This question會告訴你更多關於它是如何工作的;它也會告訴你最好不要使用它。

代碼中的三字節字符串$string是歐元符號的UTF-8表示,而不是其「unicode代碼點」(與所有常見Unicode字符一樣,爲2個字節,如0x20ac)。

這是否清除了您看到的行爲?

1

您開始的字符串是歐元符號的utf-8表示形式。如果您運行echo($string)所有版本的PHP都會生成您在$string中輸入的三個字節。瀏覽器如何解釋它們取決於Content-Type標題中指定的字符集。如果它是text/html; charset=utf-8那麼你會在渲染頁面上看到歐元符號。

然後你做錯了舉動。你只需要兩個參數即可呼叫mb_convert_encoding()。這讓PHP使用mb_string擴展使用的內部編碼的當前值作爲第三個參數($from_encoding)。爲什麼?

對於PHP 5.6及更新版本,mb_internal_encoding()返回的默認值爲utf-8,並且mb_convert_encoding()的調用爲空操作。

但是對於以前版本的PHP,mb_internal_encoding()返回的默認值是iso-8859-1,它與您的字符串的編碼不匹配。因此,mb_convert_encoding()$string的字節解釋爲三個單獨的字符並使用utf-8的規則對它們進行編碼。結果顯然是錯誤的。

順便說一句,如果你初始化$string'€'你會得到所有PHP版本(即使在PHP 4,iirc)相同的輸出。