必须用 mb_strlen($str, 'UTF-8'),因为 strlen() 按字节计数导致“你好”返回6而非用户感知的2个字符;mb_strlen() 按字符计数且显式指定编码可确保中英文、emoji等混合字符串长度准确,避免跨环境异常。

PHP 8.0 判断中英文混合字符串长度,核心就一条:用 mb_strlen($str, 'UTF-8'),别用 strlen()。
为什么必须用 mb_strlen()?
因为中文、中文标点、emoji、希伯来文等在 UTF-8 下都占多个字节:
– strlen("你好") 返回 6(每个汉字 3 字节),但用户认为是「2 个字符」;
– mb_strlen("你好", 'UTF-8') 正确返回 2;
– 同样,mb_strlen("Hello,世界!", 'UTF-8') 返回 9(H/e/l/l/o/,/世/界/!各算 1)。
不加第二个参数 'UTF-8' 是常见错误——它会依赖 mb_internal_encoding() 设置,环境一变就出错。
使用前先检查 mbstring 是否可用
PHP 8.0 默认启用 mbstring,但某些精简镜像或云函数可能没开:
PHP 8.5.12 RC 1 候选版修复 BZ2、DOM、PDO、Opcache/JIT 和扩展内存安全问题,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 运行
extension_loaded('mbstring')返回true才安全 - Docker 中 Alpine 需装
php82-mbstring(版本号按实际调整) - Apache/Nginx 环境检查
php.ini是否有extension=mbstring
边界情况处理建议
真实业务中,光计数还不够,还得防干扰:
立即学习“PHP免费学习笔记(深入)”;
- 输入前用
trim()去首尾空白,避免空格拉长“感知长度” - 过滤零宽字符(如
\u200b),它们不显示却计入mb_strlen,可用preg_replace('/[\x{200b}-\x{200f}\x{feff}]/u', '', $str) - 若需兼容 PHP str_contains() 等新函数,但
mb_strlen()在 7.2+ 已完全稳定
不要踩的坑
这些写法看着省事,实际不可靠:
- 用
strlen($s) > mb_strlen($s)推断含中文 → emoji、全角 ASCII、BOM 都会误报 - 用
mb_ereg()或mb_eregi()→ PHP 8.0+ 已废弃,不同系统行为不一致 - 依赖
mb_strlen($str)不传编码 → ini 配置一改,线上立刻出错


















