strlen()和 UTF-8 编码
假设采用UTF-8编码,在PHP中采用strlen(),那么这个字符串的长度是否有可能是4?
我只想知道strlen()的情况,而不是其他的函数
这是一个字串。
$1�2
我在自己的电脑上测试了一下,我验证了UTF-8编码,得到的答案是6。
我在strlen的手册中没有看到任何东西,也没有看到我读过的关于UTF-8的任何东西,可以解释为什么上面的一些字符会被算作小于1。
PS:这个问题和答案(4)来自于我在Ebay上购买的ZCE模拟测试。
strlen
是计算字节数,而不是计算字符数
- Esailija 2012-06-14
strlen
时,它们的长度与字节数一样多。使用 php.net/manual/en/function.mb-strlen.php 获得预期结果。
- Rem.co 2012-06-14
如何使用mb_strlen()?
http://lt.php.net/manual/en/function.mb-strlen.php
但是如果你需要使用 strlen,你可以通过设置 mbstring.func_overload 指令来配置你的 webserver,这样它就会在你的脚本中自动将 strlen 的使用替换为 mb_strlen。
mbstrung.func_overload
- 启用它将破坏我的一堆代码,因为我总是认为strlen是以字节为单位的长度。
- thomasrutter 2018-10-19
你发布的字符串有六个字符:$1�2(美元符号,数字一,小写i带重音,倒置的问号,二分之一的分数,数字二)。
如果用该字符串的UTF-8表示法调用strlen(),你会得到一个9的结果(很可能,尽管有多种不同长度的表示法)。
然而,如果我们将该字符串存储为ISO 8859-1或CP1252,我们将得到一个6个字节长的序列,作为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美元)。
需要使用多字节字符串函数mb_strlen(),如。
mb_strlen($string, 'UTF-8');
很可能在准备问题和你阅读问题之间的某个时间点上,有些过程将其中的非ASCII字符弄乱了,所以问题原本是关于某个含有4个字符的字符串的。
序列�
是在编码替换字符U时得到的UTF-8 格式的 +FFFD (�) 并以 latin1 格式解释结果。例如,在从文件中读取文本时,此字符可替代不编码任何字符的字节序列。发生的事情很可能是这样的:
最初的问题,存储在一个latin1文本文件中,有。$1¢2
(你可以用任何非ASCII字符替换¢)
该文件被一个使用UTF-8的程序读取。由于对应于"¢"的字节不能被解释,该程序将其替换,并读取了文本$1�2
。然后这个文本被用UTF-8写出来,结果在文件中出现了$1\xEF\xBF\xBD2
。
然后有第三个程序来读取拉丁文1的文件,并显示$1�2
.
不。
我将使用一个矛盾证明法。
strlen计算字节数,所以strlen为4时,该字符串中需要有精确的4个字节。
UTF8编码需要每个字符至少有1个字节。
我们已经确定了这一点。
- 有4个字节的
- 一个字符由不少于1个字节来代表
...然而,我们有6个字符....,这是一个矛盾。所以,没有。
然而,不完全清楚的是,显示软件(例如,网络浏览器)使用哪种字符集来解释该字符串。它可能使用了一些不常见的编码方案,其中一个字符可以用少于8位来表示。如果是这种情况,那么4个字节可以显示为6个字符。因此,字符串可能是utf8,但浏览器可能决定将其解释为,例如,一些5位字符集。
许多UTF-8字符需要几个字节而不是一个字节。这就是UTF-8的构造(这就是为什么你可以在一个集合中拥有这么多字符)。
试试 mb_strlen()
代替。
strlen()
计算字符串中的字节数。如果字符串有6个字节,它的结果是6。
- Madara's Ghost 2012-06-14