必须用mb_strlen($str, 'UTF-8'),因strlen()按字节计数,阿拉伯文在UTF-8中占2–4字节,导致结果远大于实际字符数;而mb_strlen按Unicode码点计数,准确返回字符个数。

PHP 8.0 判断含阿拉伯文的字符串长度,核心只有一条:必须用 mb_strlen($str, 'UTF-8'),不能用 strlen()。
为什么 strlen() 完全不可靠
阿拉伯文在 UTF-8 编码中每个字符占 2–4 字节(如 ا、ب、ت 占 2 字节;带变音符号的 حَـ 或长文本中的连字可能达 3–4 字节)。strlen() 统计的是字节数,不是字符数。例如:
-
"مرحبا"(含阿拉伯字母 + 西班牙文)实际是 6 个字符; -
strlen("مرحبا")可能返回 10–14(取决于具体字符和编码细节); - 而
mb_strlen("مرحبا", 'UTF-8')稳定返回 6。
确保 mbstring 扩展已启用
mb_strlen() 属于 mbstring 扩展,PHP 8.0 默认通常已开启,但需确认:
- 运行
php -m | grep mbstring,有输出即表示已加载; - 若无,Linux 下检查
php.ini是否含extension=mbstring;Windows 下查extension=php_mbstring.dll; - Docker 或云函数环境常被遗漏,需在构建阶段显式安装(如 Alpine 加
apk add php82-mbstring)。
编码参数不能省略
即使 PHP 8.0+ 的 mbstring.internal_encoding 默认为 UTF-8,也必须显式传入 'UTF-8':
立即学习“PHP免费学习笔记(深入)”;
- 错误写法:
mb_strlen($str)—— 依赖运行时配置,线上与本地行为可能不一致; - 正确写法:
mb_strlen($str, 'UTF-8')—— 明确、可移植、防配置漂移; - 若输入来源不确定(如旧系统 GBK 数据),先转换:
mb_convert_encoding($str, 'UTF-8', 'auto'),再测长。
后续操作也要保持多字节安全
长度判断只是第一步。阿拉伯文是右到左(RTL)文字,但 RTL 本身不影响长度计算——真正出问题的是截断、匹配等操作:
- 截取前 10 个字符?用
mb_substr($str, 0, 10, 'UTF-8'),别用substr()(会切碎字节,产生乱码); - 正则匹配?所有
preg_*函数必须加u修饰符,如preg_match('/^[\p{Arabic}]+$/u', $str); - 前端显示需配合
dir="rtl"或 CSSdirection: rtl,否则视觉顺序错乱,哪怕后端长度完全正确。



















