php判断多字节字符串长度_php多语言长度计算法【步骤】

mb_strlen() 是唯一靠谱的多字节字符串长度函数,它按字符(code point)而非字节计数,需显式指定编码如 ‘UTF-8’,否则可能退化为字节计数;处理 emoji 或组合字符应改用 grapheme_strlen() 获取视觉长度。

php判断多字节字符串长度_php多语言长度计算法【步骤】

mb_strlen() 是唯一靠谱的多字节字符串长度函数

PHP 默认的 strlen() 只按字节计数,对中文、日文、emoji 等会严重误判。比如 "你好" 在 UTF-8 下占 6 字节,strlen() 返回 6,但语义长度是 2。mb_strlen() 才真正按字符(code point)计算,前提是明确指定编码

实操要点:

  • 必须传入第二个参数,如 mb_strlen($str, 'UTF-8');不传时依赖 mb_internal_encoding(),极易出错
  • 编码名必须准确:用 'UTF-8',不是 'utf8''utf-8'(PHP 对大小写敏感,且不接受短横线)
  • 若字符串编码未知,先用 mb_detect_encoding($str, ['UTF-8', 'GB2312', 'BIG5'], true) 探测,但该函数不可靠,优先保证输入源统一为 UTF-8

处理 emoji 和组合字符要额外小心

某些 emoji(如 ?‍?)或带变音符号的字符(如 é)在 UTF-8 中由多个 Unicode 码点组成,mb_strlen() 默认按码点计,结果可能不符合视觉预期。例如 "?‍?" 由 4 个码点组成(ZJW + MAN + ZWJ + COMPUTER),mb_strlen() 返回 4,但人眼只认作 1 个“字符”。

若需视觉长度(grapheme cluster 长度),改用 grapheme_strlen()

立即学习PHP免费学习笔记(深入)”;

$str = "Hello ?‍?";
echo mb_strlen($str, 'UTF-8'); // 输出 9
echo grapheme_strlen($str); // 输出 8(更贴近显示宽度)

注意:grapheme_strlen() 依赖 intl 扩展,线上环境需确认已启用。

Upscalepics

Upscalepics

在线图片放大工具

下载

替代方案:substr() 和 mb_substr() 切片必须配套使用

长度判断和截断必须用同一套逻辑,否则索引错位。用 strlen() 判断长度却用 mb_substr() 截取,大概率乱码或截半字符。

正确做法:

  • 统一用 mb_strlen() 判断长度
  • 统一用 mb_substr($str, $start, $length, 'UTF-8') 截取,第三个参数是字符数,不是字节数
  • 避免混用 substr() / mb_substr(),尤其当字符串含中文或 emoji 时

性能差异小,但编码缺失会导致静默错误

mb_strlen()strlen() 略慢(因需解析多字节序列),但在绝大多数 Web 场景中可忽略。真正的风险在于漏写编码参数——它不会报错,只是退化成类似 strlen() 的行为,问题在线上才暴露,且难以复现。

建议在项目初始化处强制设置:
mb_internal_encoding('UTF-8');,再全局使用无编码参数的 mb_strlen($str)。但更推荐显式传参,避免依赖全局状态。

最易被忽略的是:数据库连接、HTTP 请求头、文件读取等环节若未统一 UTF-8,mb_strlen() 再准也救不了源头乱码。

https://www.php.cn/faq/2035465.html

发表回复

Your email address will not be published. Required fields are marked *