2012-06-14 29 views
9

假設在PHP中使用UTF-8編碼和strlen(),該字符串的長度是否可能爲4?strlen()和UTF-8編碼

我只是有興趣瞭解的strlen(),而不是其他功能

這是字符串:$1�2

我測試我自己的電腦上,我已經驗證UTF -8編碼,我得到的答案是6.

我沒有在手冊中看到strlen或任何我在UTF-8上讀過的東西,這可以解釋爲什麼上面的一些字符會算少不止一個。

PS:這個問題和答案(4)來自我在Ebay上購買的ZCE的模擬測試。

PPS:請把我的骨頭投給我。我做了我的功課。預先感謝所有回覆和投票。

+4

'strlen'計數字節,而不是字符 – Esailija

+0

當使用'strlen'時,UTF-8字符是多字節字符,並且計爲字節長度爲as-many-characters-as-many-in-bytes。使用http://php.net/manual/en/function.mb-strlen.php獲得預期結果。 –

+4

@RemcoOverdijk utf-8編碼的字符可以是1-6個字節長。 – Esailija

回答

8

您發佈的字符串爲六個字符長:$1�2(美元符號,數字一個字母,小寫字母我二分法,倒問號,一個半部分,數字二)

如果strlen的()被用該字符串的UTF-8表示調用時,您會得到9的結果(可能,雖然有多個不同長度的表示)。

但是,如果我們要將該字符串存儲爲ISO 8859-1或CP1252,那麼我們將有一個六字節長的序列,這與UTF-8一樣合法。將這6個字節重新解釋爲UTF-8將導致4個字符:$1 2(美元符號,數字1,Unicode替換字符,數字2)。也就是說,單個字符「 」的UTF-8編碼與三個字符「½」的ISO-8859-1編碼相同。

當UTF-8解碼器讀取的數據不是有效的UTF-8數據時,經常會插入替換字符。

看起來原來的字符串是經過多層誤解處理的;通過在非UTF-8數據上使用UTF-8解碼器(產生1美元2),然後通過您用來分析該數據的任何內容(產生1美元2)來實現。

15

如何使用mb_strlen()?

http://lt.php.net/manual/en/function.mb-strlen.php

但是,如果你需要的strlen使用,它可以通過指令的mbstring.func_overload設置爲2來配置你的服務器,所以它會自動替換使用strlen的在你的腳本mb_strlen。

+1

是的,我在其他答案中看到mb_strlen(),但我特別看着strlen() –

+0

修復了我的答案來回答你的評論問題。 – Anton

+0

謝謝。不回答這個問題。抱歉。 –

1

許多UTF-8字符需要幾個字節而不是一個。這就是UTF-8的構建方式(這就是爲什麼你可以在一組中有這麼多字符)。

嘗試mb_strlen()改爲。

+0

fun-fact:在理論上,utf-8每個字符最多可以使用8個字節,儘管這個長度在目前還沒有被使用 - 最大使用長度是一堆四字節字符(如Clef-sign和一些例如中文字符)。 – oezi

+0

strlen()怎麼樣?答案可能小於6嗎? –

+0

@JonLyles:'strlen()'計算字符串中的字節數。如果字符串有6個字節,則結果爲6. –

5

需要使用多字節字符串函數mb_strlen(),如:

mb_strlen($string, 'UTF-8'); 
2

,我會用反證法使用證明。

strlen counts bytes,因此在strlen爲4的情況下,需要在該字符串中的正好4個字節

UTF8編碼需求每個字符至少1個字節

我們已經確定:

  1. 有4個字節
  2. 一個字符由不低於1個字節

代表......然而,我們有6個字符...這是一個矛盾。所以不行。

但是,不清楚顯示軟件(例如Web瀏覽器)使用哪個字符來解釋字符串。它可以使用一些不常用的編碼方案,其中一個字符可以少於8位表示。如果是這種情況,則4個字節可以顯示爲6個字符。所以,字符串可能是utf8,但瀏覽器可能會將其解釋爲5位字符集。

+0

更多信息。謝謝。 –

5

在編寫問題和讀取它之間的某個時間點,某些進程可能會破壞非ASCII字符,因此問題最初是關於一些字符串,其中包含4個字符。

使用UTF-8對replacement character U+FFFD( )進行編碼並將結果解釋爲latin1時,獲得序列�。例如,此字符用作字符序列的替代品,例如,在從文件中讀取文本時不對任何字符進行編碼。現在的情況是可能的:

原來的問題,存儲在latin1的文本文件,有:$1¢2(你可以用任何非ASCII字符替換¢)

該文件是由使用的程序的讀取UTF-8。由於無法解釋與¢對應的字節,因此程序將其替換並讀取文本$1�2。然後使用UTF-8寫出該文本,從而在該文件中產生$1\xEF\xBF\xBD2

然後第三個程序來讀取拉丁文中的文件,並顯示$1�2

+0

非常有幫助謝謝 –