mb_substr按字符截取,能准确处理UTF-8中文等多字节字符;substr按字节截取易导致乱码;mb_substr需显式指定编码如'UTF-8',而mb_strcut仍以字节为单位,可能用?替代不完整字符。

因为 mb_substr 按字符(character)截取,不是按字节(byte)截取。
中文在UTF-8里是多字节字符
一个汉字在 UTF-8 编码下占 3 个字节。而普通英文、数字、标点只占 1 个字节。substr() 不识别字符边界,它直接从第 N 个字节开始切、切 M 个字节——如果正好切在某个汉字的中间两个字节之间,就会留下不完整的字节序列,浏览器或终端无法解析,显示为 或其他乱码。
mb_substr() 内部使用字符编码映射表(如 UTF-8 的 Unicode 码点规则),能准确识别出“这 3 个字节合起来才是一个‘你’字”,所以它总是整字整字地切,不会打断任何一个中文、日文、emoji 或带重音的拉丁字母。
mb_substr 依赖 mbstring 扩展的编码解析能力
PHP 的 mbstring 扩展内置了对多种编码(UTF-8、GBK、BIG5 等)的完整支持。调用 mb_substr($str, 0, 5, 'UTF-8') 时:
- 它先将字符串按 UTF-8 规则解码成字符序列(例如:"你好world" → ['你', '好', 'w', 'o', 'r', 'l', 'd'])
- 再从中取前 5 个字符 → "你好wor"
- 最后按 UTF-8 编码规则重新拼成字节流输出
整个过程绕开了“字节位置”这个危险概念,全程在语义正确的字符层面操作。
必须显式传入编码参数
即使项目默认是 UTF-8,也建议始终写明第三个编码参数:
- 避免依赖 mb_internal_encoding() 设置,防止线上环境不一致
- 防止因 mbstring.func_overload 开启导致行为意外偏移
- 让代码意图清晰,后续维护者一眼看懂处理逻辑
错误写法:mb_substr($s, 0, 10)(编码靠猜)
正确写法:mb_substr($s, 0, 10, 'UTF-8')
对比 mb_strcut:它仍以字节为单位
mb_strcut 看似“安全”,但它是在字节层面对齐截断,遇到跨字节字符被切开时,会用 ? 替代,结果可能是 "百度智?" 而不是 "百度智"。它不保证语义完整,只保证输出可显示——这不是真正解决乱码,只是掩盖问题。
真正防乱码、保语义、适配多语言的唯一推荐方式,就是 mb_substr + 显式编码参数。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











