必须用 mb_substr() 而非 substr(),因后者按字节截取会导致中文、emoji 乱码;mb_substr() 按字符操作,需显式指定 'UTF-8' 编码,支持负数起始/长度,配合 mb_strlen() 可避免越界。

直接用 mb_substr(),别用 substr()——后者按字节切,中文、emoji 一截就乱码。
为什么必须用 mb_substr?
UTF-8 中一个中文字符占 3 字节,substr("你好", 0, 2) 会取前 2 个字节,结果是半个字符,显示为 或其他乱码。
而 mb_substr() 按“字符”数操作,mb_substr("你好", 0, 1, 'UTF-8') 稳稳输出“你”。
四个参数怎么填?
$str:要处理的字符串,没特别要求;
$start:从第几个字符开始(0 起始),负数表示从末尾倒数;
$length(可选):要取几个字符,省略则取到末尾,负数表示“去掉末尾若干字符”;
$encoding(强烈建议显式传):编码格式,最常用 'UTF-8',不能省。
-
mb_substr("测试文本", 2, 3, 'UTF-8')→ “文本”(从第 2 字符起取 3 个) -
mb_substr("测试文本", -2, 1, 'UTF-8')→ “文”(倒数第 2 个字符开始,取 1 个) -
mb_substr("abcde", 0, -2, 'UTF-8')→ “abc”(去掉末尾 2 个字符)
常见踩坑点
不指定 $encoding 是最大隐患:系统默认可能不是 UTF-8,尤其在宝塔、Docker 或老环境里,mb_substr("你好", 0, 2) 可能返回空或乱码。
另外,$start 绝对值超过字符串字符数时,函数安静地返回空字符串,不会报错,容易漏排查。
- ✅ 正确写法:
mb_substr($str, 0, 20, 'UTF-8') - ❌ 危险写法:
mb_substr($str, 0, 20)(依赖mb_internal_encoding(),不可靠) - ⚠️ 注意:
mb_strlen($str, 'UTF-8')应配合使用,判断长度再截取,避免越界
和 mb_strcut 有什么区别?
mb_substr 是按字符切,安全但稍慢;mb_strcut 是按字节切,快 15%–30%,但可能把一个中文卡在中间,变成“百度智?”。
除非你在做日志截断或固定字段填充且能接受乱码风险,否则一律选 mb_substr。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











