核心区别在于substr按字节操作而mb_substr按字符操作:前者易对中文、emoji等多字节字符造成乱码,后者依UTF-8编码结构准确截取;参数单位、编码依赖及适用场景均不同。

核心区别在于:substr 按字节操作,mb_substr 按字符操作——这对中文、日文、emoji 等多字节字符是否乱码起决定性作用。
截断单位完全不同
substr 把字符串当成一串字节流,不管编码,直接从第 N 个字节开始取 M 个字节。UTF-8 中一个中文占 3 字节,若在中间截断(比如取 4 字节),就会输出半个汉字,显示为 或乱码。
- 例:
$str = "你好"; echo substr($str, 0, 4);→ 输出"你"(前 3 字节是“你”,第 4 字节是“好”的第一个字节,不完整) - mb_substr 则识别 UTF-8 编码结构,把“你好”当作 2 个独立字符,
mb_substr($str, 0, 1)稳定返回"你",不会切开任何字符
长度和位置的计量基准不同
substr 的 $start 和 $length 是字节数;mb_substr 的对应参数是字符数。
-
strlen("✅PHP")返回 6(✅ 占 4 字节,P/H/P 各 1 字节) -
mb_strlen("✅PHP", "UTF-8")返回 4(✅ 算 1 个字符) - 所以
substr("✅PHP", 0, 2)取前 2 字节(可能只拿到 ✅ 的一半),而mb_substr("✅PHP", 0, 2)稳定取前 2 个字符(✅ 和 P)
编码依赖与默认行为
substr 完全不关心编码,也不接受编码参数;mb_substr 必须知道编码才能正确解析字符边界。
- PHP 7.4 中,mb_substr 第四个参数
$encoding可省略,但会 fallback 到mb_internal_encoding()的值(推荐显式传"UTF-8") - 若未设置内部编码或传错(如用
"GBK"解析 UTF-8 字符串),mb_substr 也会出错或返回空 - 确保 php.ini 已启用
extension=mbstring,否则调用 mb_substr 会报 fatal error
性能与适用场景
substr 更快,因为无编码解析开销;mb_substr 稍慢,但安全——这不是“要不要用”的权衡,而是“能不能用”的前提。
- 纯英文/数字 URL、文件名、token 等 ASCII 场景,可用 substr
- 用户昵称、评论、标题、数据库字段等含中文、emoji、外文的场景,必须用 mb_substr
- 别混用:用
mb_strlen计算长度,就该用mb_substr截取;用strlen就只能配substr
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











