必须用 grapheme_strlen() 而非 strlen() 或 mb_strlen() 判断 Emoji 字符串长度,因它按 Unicode 图形簇计数,能正确将 ??、❤️ 等视为 1 个可见字符,且 PHP 7.2 已内置支持。

PHP 7.2 判断 Emoji 字符串长度,核心是**不能用 strlen(),必须按 Unicode 字符(而非字节)计数**。因为 Emoji 在 UTF-8 中多为 4 字节(如 ?、?、??),strlen() 会返回字节数(如 4、8、16),而用户和前端看到的“长度”是 1、1、1 或 2(取决于是否含代理对)。
用 mb_strlen() 获取基础字符数
这是最常用且正确的起点:
-
mb_strlen($str, 'UTF-8')返回字符串中 UTF-8 编码的 Unicode 码点个数 - 对大多数 Emoji(如 ?、?、❤️),它返回 1
- 对带 ZWJ 连接符的组合 Emoji(如 ??、?❤️??),它通常返回 4–7(因拆成多个码点),但视觉上仍是 1 个
- 务必显式传入
'UTF-8',避免依赖mb_internal_encoding()的不确定状态
识别并统计“真实可见字符”个数(推荐用于表单/显示限制)
若需更贴近人眼感知(比如“最多输入 10 个表情符号”),应使用 grapheme_strlen():
- 该函数基于 Unicode 图形簇(grapheme cluster)计数,能正确将 ??、??、❤️ 视为 1 个单位
- PHP 7.2 已内置支持,无需额外扩展(确保
intl扩展已启用) - 示例:
grapheme_strlen("Hello ????")返回 11(字母+空格+3 个图形簇) - 注意:若输入非合法 UTF-8,函数可能返回
false,建议先用mb_check_encoding($str, 'UTF-8')校验
快速检测字符串是否含 Emoji(辅助判断逻辑)
有时你只需知道“有没有 Emoji”,不一定要精确计数:
立即学习“PHP免费学习笔记(深入)”;
- 利用 Emoji 多为 4 字节 UTF-8 字符的特性(基本平面外字符)
- 遍历每个字符,用
mb_substr($str, $i, 1, 'UTF-8')提取单字符,再用strlen()测其字节数 - 若任一子串
strlen() >= 4,大概率是 Emoji 或生僻汉字(可结合正则进一步过滤) - 简单函数示例:
function hasEmoji($str) {<br> $len = mb_strlen($str, 'UTF-8');<br> for ($i = 0; $i < $len; $i++) {<br> $char = mb_substr($str, $i, 1, 'UTF-8');<br> if (strlen($char) >= 4) return true;<br> }<br> return false;<br>}
前后端长度对齐要点(避免校验失败)
用户在前端输入 5 个 Emoji,后端却判超长?常见原因:
- 前端用
"?".length === 2(UTF-16 代理对),而后端用mb_strlen()得到 1 —— 二者模型不同 - 真正对齐做法:前端也按图形单位计数,例如
Array.from("???").length(返回 2),或用Intl.Segmenter(现代浏览器) - 后端统一用
grapheme_strlen(),比模拟 JS 的length更合理、更稳定 - 数据库字段(如
VARCHAR(100))按字符存储,与grapheme_strlen()语义一致;勿用strlen()做入库前校验



















