Menu

PHP strlen():按字节和按字符计算字符串长度

strlen($string) 返回字符串的字节长度,mb_strlen($string) 返回字符长度。了解为什么中文、日文和 emoji 会得到不同的结果,怎么判断空字符串,以及怎么校验输入长度。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

strlen($string) 返回字符串的字节长度。要得到字符数(处理中文、日文、带重音的字母和 emoji 时你需要的正是它),用 mb_strlen($string)。对于纯英文文本,两者的结果相同。

空格、标点和换行都算在内。strlen("a b\n") 是 4。

UTF-8 中的字节和字符

PHP 字符串是字节序列,而 UTF-8 中每个字符占用的字节数不同:ASCII 字母和数字占 1 个,é 或 ж 这样的字母占 2 个,假名、常用汉字和 € 这样的符号占 3 个,大多数 emoji 和 𠮷 这样的生僻字占 4 个。strlen() 把字节加起来,mb_strlen() 数的是字符。用文本转二进制工具可以看到任意字符串背后的字节。

字节数重要时用 strlen():按字节限制长度的数据库列、文件大小、二进制协议。凡是给人看的内容都用 mb_strlen():字数统计、“最多 20 个字”的规则、用 mb_substr() 截取文本。

emoji 和由多个码位组成的字符

mb_strlen() 统计的是 Unicode 码位。有些在读者看来是一个字符的东西,其实是几个码位连在一起:家庭 emoji、旗帜、肤色,或者一个字母加一个组合重音符。

要统计读者眼中的单个字符(字素簇),需要 intl 扩展中的 grapheme_strlen():

echo grapheme_strlen('👨‍👩‍👧');   // 1
echo grapheme_strlen('🇯🇵');     // 1

对于中文或日文表单上的字数统计,mb_strlen() 通常就够了:每个汉字和假名都是一个码位。

用 mb_strwidth 计算显示宽度

在终端或等宽排版中,一个全角的中文或日文字符占两列,而半角片假名或拉丁字母占一列。mb_strwidth() 返回的就是这个宽度,“全角字符算 2 个字”这类规则通常指的正是它。

判断字符串是否为空

最清楚的写法是和 '' 严格比较。strlen($s) === 0 的结果相同。empty($s) 则不一样:它对字符串 "0" 也返回 true,而在很多表单里 "0" 是一个有效的答案。

只有空格的字符串不是空的。如果只有空格也应该算作没有内容,先用 trim() 处理一下。

strlen(null) 和非字符串

strlen() 需要一个字符串。传入 null 仍然返回 0,但从 PHP 8.1 开始会打印一条弃用提示:

Deprecated: strlen(): Passing null to parameter #1 ($string) of type string is deprecated in /home/index.php on line 2

传入数组会抛出 TypeError: strlen(): Argument #1 ($string) must be of type string, array given。

先转换类型或给一个默认值,比如 strlen($value ?? '')。整数会被转换成字符串,所以 strlen(12345) 是 5。要统计数组元素,用 count()。

校验用户输入的长度

一个典型的规则:去掉首尾空格后,用户名长度为 3 到 16 个字符。用 mb_strlen(),这样日文或中文名字按字符而不是按字节计算。

如果把 mb_strlen() 换成 strlen(),やまだたろう 会被算成 18,并因为太长而被拒绝,尽管它只有六个字符。

常见问题

PHP 中怎么获取字符串的长度?

strlen($s) 返回字节数,mb_strlen($s) 返回字符数。对于纯英文文本两者相同;对于中文、日文、带重音的字母或 emoji,用 mb_strlen()。

为什么 strlen() 对中文、日文文本返回的长度不对?

它没有错,它数的是字节。UTF-8 中假名、常用汉字各占 3 个字节,所以 strlen('日本語') 是 9,而 mb_strlen('日本語') 是 3。

怎么统计包含 emoji 的字符串的字符数?

mb_strlen() 统计的是 Unicode 码位,所以简单的 emoji 算 1 个,但由多个码位组成的 emoji(家庭、旗帜、肤色)会算成多个。intl 扩展中的 grapheme_strlen() 统计的是读者眼中的一个字符。

PHP 中 strlen 和 count 有什么区别?

strlen() 测量字符串,count() 统计数组的元素个数。在 PHP 8 中把数组传给 strlen() 会抛出 TypeError。

PHP 中怎么判断字符串是否为空?

和空字符串比较:$s === '',或者 strlen($s) === 0。不要用 empty($s) 做这件事,因为它把字符串 "0" 也当作空。

Coddy 编程语言插图

和 Coddy 一起学编程

开始