Php5 - Unicode字符串长度

时间:2011-11-08 09:16:00

标签: php unicode character-encoding

我需要通过HTTP Post / get获得正确长度的unicode文本。

“हेल्लोस्टैकओवरफ्लो”

当我将浏览器的字符编码设置为Unicode时,那么 mb_strlen($ text)给出了正确的unicode字符串长度,即20。

但是当我使用编码为'ISO-8859-1'的浏览器提交表单时,它表现得很奇怪。 mb_strlen($ text)给出了unicode字符串的字节长度,这是128,这是错的,也是

mb_detect_encoding($ text,“auto”)返回ascii。 而 mb_detect_encoding($ text,“UTF-8”)返回UTF-8。

无论浏览器字符集如何,我都需要正确长度的unicode文本。

任何人都可以帮我解决这个问题吗?

此致 的Sandip

2 个答案:

答案 0 :(得分:2)

ISO-8859-1,又名西欧字符集,是指扩展的罗马字母,它不包括您在上面指定的字符(是印地语吗?我不太熟悉这些语言)。 mb_detect_encoding调用不会检测到您的编码,因为您将字符修改为ISO-8869-1,它不支持您提供的字符。

您应指定支持您需要显示的字符类型的编码。 UTF-8可能是你最好的选择。您可以使用Content-Encoding标头在HTTP标头中显式设置编码。您也可以在HTML中的meta标记中重复此操作,以获得最大支持。

答案 1 :(得分:1)

  

无论浏览器字符集如何,我都需要正确长度的unicode文本。

如果您不知道编码,则无法知道长度。一串字节可以同时表示不同编码中的不同有效字符串。 mb_detect_charset只会给你一个不可靠的猜测。

许多现代浏览器都支持他们告诉你他们使用了什么编码,这是一种偷偷摸摸的方式,包括这种黑客攻击(源自IE):

<input type="hidden" name="_charset_"/>

然后,您将获得在该字段中提交的编码名称,理论上您可以将mb_convert_encoding用于收到UTF-8的字符串用于进一步处理。您肯定希望将所有字符串保存在脚本中的单个编码中,只在必要时转换为输入/输出端的其他编码;试图在任意编码中跟踪字节串是非常不愉快的。

但是,您无法将包含हेल्लो...的ISO-8859-1字符串转换为UTF-8,因为ISO-8859-1不能包含这些字符。您的数据已经损坏,如deceze所述:当您以不包含字符的编码提交表单数据时,浏览器会使用HTML &#...;字符引用来转义它们。这是一个无法准确恢复的有损转换,因为您无法区分这些转义与用户最初键入的实际&符号和哈希序列之间的区别。永远不要依赖这种长期但又古怪且不受欢迎的行为。

一般来说,确保表单提交始终使用涵盖您可能需要的所有字符的已知编码,确实更好。这样您就不必担心转换,或者是否存在任何字符引用错误。为此目的唯一合理的编码是UTF-8。 (UTF-16除了普遍效率低之外还有一些浏览器问题。)

浏览器使用与显示页面相同的编码提交表单,因此请使用Content-Type: text/html;charset=utf-8标题和/或<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>等效项来指定页面编码,而不是让浏览器猜测。然后,它将使用该编码进行表单提交。

唯一剩下的皱纹是,如果用户故意覆盖带有表单的页面编码,您将收到错误的数据提交。除非您的页面已经损坏,否则这种情况不太可能发生,所以通常不值得打扰。

如果您想要涵盖这种可能性,可以在表单上设置属性accept-charset。然而!这在IE中不起作用,IE只将accept-charset视为后备建议,因为它的表单数据不符合页面的自然编码。如果你想确保你获得UTF-8,即使面对用户将编码更改为其他内容,你也必须在表单中包含一些数据,这些数据不能用任何其他编码进行编码。能够挑选。传统的做法是:

<form accept-charset="utf-8">
    <input type="hidden" name="unicodesnowman" value="&#x2603;"/>
    ...