13

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

我只对 strlen() 感兴趣,而不是其他函数

这是字符串:

$1�2

我在自己的电脑上测试过,验证了UTF-8编码,得到的答案是6。

我没有在 strlen 的手册中看到任何内容,也没有在 UTF-8 上阅读过任何内容来解释为什么上面的某些字符的计数小于一个。

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

4

6 回答 6

19

如何使用 mb_strlen() ?

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

但是如果您需要使用 strlen,可以通过将 mbstring.func_overload 指令设置为 2 来配置您的网络服务器,因此它会自动在您的脚本中将 strlen 的使用替换为 mb_strlen。

于 2012-06-14T13:27:04.713 回答
14

您发布的字符串有六个字符长:$1�2(美元符号,数字一,带分音符号的小写 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)。

于 2012-06-14T21:57:36.403 回答
10

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

mb_strlen($string, 'UTF-8');
于 2012-06-14T13:28:41.297 回答
5

很可能在准备问题和阅读问题之间的某个时间点,某些过程已经破坏了其中的非 ASCII 字符,因此问题最初是关于其中包含 4 个字符的某个字符串。

当您以 UTF-8 对替换字符 U+FFFD (�) 进行编码并以 latin1 解释结果�时,将获得该序列。例如,在从文件中读取文本时,此字符可替代不编码任何字符的字节序列。发生的事情很可能是这样的:

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

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

然后出现了第三个程序,它读取 latin1 中的文件,并显示$1�2.

于 2012-06-14T14:13:22.127 回答
2

不。

我将使用反证法。

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

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

我们已经确定:

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

...然而,我们有 6 个字符....这是一个矛盾。所以不行。

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

于 2012-06-14T14:07:31.197 回答
1

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

试试mb_strlen()吧。

于 2012-06-14T13:27:35.650 回答