strlen() 返回字节数而非字符数,阿拉伯文UTF-8编码下每字符占2–4字节,故结果偏大;应使用mb_strlen($str, 'UTF-8')并显式指定编码,确保正确统计字符数。

PHP 中 strlen() 为什么对阿拉伯文返回错误长度?
strlen() 统计的是字节数,不是字符数。阿拉伯文(如 "مرحبا")在 UTF-8 编码下每个字符占 2–4 字节,strlen() 会把一个阿拉伯字母算作多个“长度”,比如 strlen("مرحبا") 返回 12,而实际只有 6 个字符。
用 mb_strlen() 替代,但必须指定 'UTF-8'
PHP 的多字节函数能正确识别 Unicode 字符,但 mb_strlen() 默认使用 mb_internal_encoding() 的值——这个值可能不是 'UTF-8'(尤其在旧环境或未显式设置时),导致结果仍不准。
实操建议:
- 始终显式传入
'UTF-8'作为第二个参数:mb_strlen($str, 'UTF-8') - 避免依赖
mb_internal_encoding(),它可能被其他代码修改,且不同 PHP 版本默认值不一致 - 如果字符串来源不可控(如 POST 数据、文件读取),先用
mb_detect_encoding($str, ['UTF-8', 'ISO-8859-1'], true)验证编码,再转换:$str = mb_convert_encoding($str, 'UTF-8', 'auto')
判断是否含阿拉伯文字母的简单方式
仅靠长度不够,有时需确认字符串里**确实有阿拉伯字符**。正则最直接:
立即学习“PHP免费学习笔记(深入)”;
if (preg_match('/[\x{0600}-\x{06FF}]/u', $str)) {
// 含阿拉伯文区块字符(基本阿拉伯字母、数字、标点)
}
注意点:
-
/u修饰符必不可少,否则 Unicode 范围匹配失效 -
\x{0600}-\x{06FF}覆盖标准阿拉伯语,但不含扩展字符(如\x{08A0}-\x{08FF}是阿拉伯补充),按需叠加 - 避免用
mb_ereg(),该系列函数在 PHP 8.2+ 已废弃,且性能差
性能与兼容性提醒
mb_strlen() 比 strlen() 慢,因为要解析 UTF-8 字节流;但在处理含阿拉伯文、中文等多字节文本时,这是必须付出的代价。
容易忽略的细节:
- 某些老旧服务器没启用
mbstring扩展,调用mb_strlen()会报Fatal error: Uncaught Error: Call to undefined function mb_strlen() - 上线前务必检查:
extension_loaded('mbstring'),否则 fallback 方案(如用iconv_strlen($str, 'UTF-8'))得提前准备好 - 不要用
count(array_filter(str_split($str)))这类“伪多字节”方案——它在 UTF-8 下完全不可靠











