strlen()和UTF-8编码

时间:2012-06-14 13:24:58

标签: php unicode utf-8 strlen

假设PHP中的UTF-8编码和strlen(),这个字符串的长度是4吗?

我只想知道strlen(),而不是其他函数

这是字符串:

  

$1�2

我已在自己的计算机上测试过,我已经验证了UTF-8编码,我得到的答案是6。

我在strlen手册或者我在UTF-8上读过的任何内容中都没有看到任何可以解释为什么上面的一些字符会少于一个的原因。

PS:这个问题和答案(4)来自我在Ebay上购买的ZCE的模拟测试。

6 个答案:

答案 0 :(得分:19)

如何使用mb_strlen()?

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

但是如果你需要使用strlen,可以通过将mbstring.func_overload指令设置为2来配置你的web服务器,这样它就会在你的脚本中自动替换使用strlen到mb_strlen。

答案 1 :(得分:9)

您发布的字符串长度为六个字符:$1�2(美元符号,数字1,带分音符的小写字母i,颠倒问号,一半分数,数字二)

如果使用该字符串的UTF-8表示调用strlen(),则会得到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)。

答案 2 :(得分:8)

需要使用多字节字符串函数mb_strlen(),如:

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

答案 3 :(得分:5)

在问题的准备和你的阅读之间的某个时刻,某些进程可能会破坏其中的非ASCII字符,因此问题最初是关于一些包含4个字符的字符串。

在UTF-8中编码replacement character U+FFFD( )并在latin1中解释结果时,会获得序列�。例如,此字符用于替换在从文件读取文本时不对任何字符进行编码的字节序列。发生了什么事可能是这样的:

存储在latin1文本文件中的原始问题包含:$1¢2(您可以将¢替换为任何非ASCII字符)

该文件由使用UTF-8的程序读取。由于无法解释对应于¢的字节,程序将其替换并读取文本$1�2。然后使用UTF-8写出该文本,在文件中生成$1\xEF\xBF\xBD2

然后是第三个程序来读取latin1中的文件,并显示$1�2

答案 4 :(得分:2)

没有

我会用矛盾证明。

strlen计算字节数,因此如果strlen为4,则该字符串中需要正好为4个字节

UTF8编码需要每个字符至少1个字节

我们已经确定:

  1. 有4个字节
  2. 字符由不少于1个字节
  3. 表示

    ......但是,我们有6个字符......这是一个矛盾。所以,没有。

    然而,还不完全清楚的是显示软件(例如,网络浏览器)使用哪个字符集来解释字符串。它可以使用一些不常见的编码方案,其中字符可以由少于8位表示。如果是这种情况,那么4个字节可以显示为6个字符。因此,字符串可以是utf8,但浏览器可以决定将其解释为例如一些5位字符集。

答案 5 :(得分:1)

许多UTF-8字符占用几个字节而不是一个字节。这就是UTF-8的构造方式(这就是你在一个集合中拥有如此多字符的方式)。

请尝试 mb_strlen()