PHP中截取中文应使用mb_substr()函数,因其按字符而非字节操作,可避免UTF-8下乱码;需显式指定'UTF-8'编码,起始位置从0计,负数表示倒序,配合mb_strlen校验长度更安全。

因为 substr() 是按字节截取的,而中文在 UTF-8 编码下占 3 个字节。当指定的截取长度刚好落在某个汉字的中间字节位置时,就会把一个完整的汉字“砍断”,导致后续字节被错误解析,显示为乱码。
substr 的底层逻辑是字节操作
它不识别字符边界,只数字节:
- 英文、数字:1 字节 → 安全截取
- UTF-8 中文:通常 3 字节(如“你” =
0xE4 0xBD 0xA0)→ 若从第 2 字节开始截,就只剩0xBD 0xA0,这不是合法 UTF-8 序列 - 截断点卡在多字节字符中间 → 输出无法解码的二进制片段 → 浏览器或终端显示或乱码
PHP 7.4 并未改变 substr 行为
PHP 7.4 仍默认使用字节级字符串处理。即使启用了 mbstring 扩展,substr() 本身也不会自动升级为多字节安全 —— 它始终是原生字节函数,和 PHP 版本无关。乱码不是 7.4 特有,而是所有 PHP 版本中对 UTF-8 中文用 substr 的共性问题。
正确做法:改用 mb_substr 或 mb_strcut
这两个函数专为多字节编码设计,能按“字符数”而非“字节数”截取:
- mb_substr($str, $start, $length, 'utf-8'):按字符计数,推荐用于标题、摘要等需语义完整场景
- mb_strcut($str, $start, $length, 'utf-8'):按字节数截,但保证不切断多字节字符,适合严格长度限制(如协议字段)
- 必须确保
php.ini中已启用extension=mbstring,且编码参数明确传入(如'utf-8')
额外注意点
即使用了 mb_substr,以下情况仍可能出乱码:
- 源字符串本身不是 UTF-8(比如 GBK 编码却传
'utf-8') - PHP 内部编码未设为 UTF-8(可通过
mb_internal_encoding('UTF-8')显式设置) - 输出环境不支持 UTF-8(如未加
header('Content-Type: text/html; charset=utf-8')或 HTML 缺)
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











