必须用mb_strlen($title, 'UTF-8')按字符数判断,因strlen()按字节计数会导致“你好”返回6而非2,引发截断错位;配套使用mb_substr($title, 0, 30, 'UTF-8')安全截取,并校验编码确保UTF-8纯净。

PHP 8.1 判断字符串长度用于标题截断,核心是**按用户感知的字符数处理**,而非字节数。中文、emoji、日文等 UTF-8 多字节字符用 strlen() 会严重高估(如“你好”返回 6),导致截断错位、乱码或逻辑错误。必须用 mb_strlen() 和 mb_substr() 配套操作,并显式指定编码。
统一用 mb_strlen() 校验字符数
所有长度判断逻辑都应基于字符维度:
- 写法:
mb_strlen($title, 'UTF-8')—— 第二个参数必须显式传'UTF-8',避免依赖mb_internal_encoding()的不确定配置 - 示例:
mb_strlen('PHP开发者?', 'UTF-8')返回 9(7个汉字 + 1个字母 + 1个 emoji),符合用户直觉 - 校验超限:
if (mb_strlen($title ?? '', 'UTF-8') > 30) { /* 截断或报错 */ }
用 mb_substr() 安全截断,不切坏字符
substr() 按字节截,极易把一个中文或 emoji 拆成乱码字节;mb_substr() 按字符边界操作,安全可靠:
- 写法:
mb_substr($title, 0, 30, 'UTF-8')表示“取前 30 个字符”,不是 30 字节 - 自动适配不足长度:若原字符串只有 22 字符,
mb_substr()直接返回全部,不会补空或报错 - 注意:起始位置和长度单位都是“字符”,不是字节;省略第三个参数会默认用内部编码,线上环境易出问题
加省略号(…)且保总长 ≤ 限制值
常见需求是“最多显示 30 字符,超长则结尾加 …”,但要确保加完后仍不超标:
立即学习“PHP免费学习笔记(深入)”;
- 预留空间:先截
30 - 1 = 29字符,再判断是否需要加点 - 代码示例:
$truncated = mb_substr($title, 0, 29, 'UTF-8');<br>if (mb_strlen($title, 'UTF-8') > 29) {<br> $truncated .= '…';<br>} - 这样最终长度一定是 ≤ 30 字符(29 + 1),且不会因“…”本身被误算为多字节而溢出
额外检查项:避免编码污染
即使函数用对,数据源不干净也会让长度判断失效:
- 接收表单后,先做基础清洗:
$title = trim($_POST['title'] ?? '') - 验证是否真为 UTF-8:
if (!mb_check_encoding($title, 'UTF-8')) { $title = mb_convert_encoding($title, 'UTF-8', 'auto'); } - 数据库连接、HTTP 请求头、文件读取等环节确认使用
utf8mb4编码,防止中文存成乱码字节再被当“合法字符”计数



















