PHP 8.1 中截取含中文字符串应使用 mb_substr($str, $start, $length, 'UTF-8'),按字符而非字节截取并显式指定 UTF-8 编码,避免 substr() 导致的乱码;mbstring 扩展默认启用,无需额外开启。

PHP 8.1 中截取含中文的字符串,关键在于别用 substr() 直接按字节切——它会把 UTF-8 的中文字符(3 字节)从中劈开,导致乱码。正确做法是按“字符”而非“字节”截取,且必须明确指定编码。
首选 mb_substr():简洁可靠
这是最推荐的方式,前提是 PHP 已启用 mbstring 扩展(PHP 8.1 默认已启用,无需额外开启)。
-
语法:
mb_substr($str, $start, $length, 'UTF-8') -
注意:第四个参数
'UTF-8'必须显式传入,不能省略;大小写不敏感,但建议全大写保持一致性 -
示例:
mb_substr("Hello世界你好", 0, 6, 'UTF-8')→"Hello世"(6 个字符,不是 6 字节)
备选 iconv_substr():兼容旧环境
如果因特殊原因禁用了 mbstring,可用 iconv_substr() 替代,功能类似:
-
语法:
iconv_substr($str, $start, $length, 'UTF-8') -
限制:依赖
iconv扩展(PHP 8.1 默认启用),但对某些边缘编码支持略弱于 mbstring -
提示:不建议在新项目中优先选用,
mb_*系列是 PHP 官方主推的多字节处理方案
避免手动解析 UTF-8 字节:没必要且易错
网上流传的“遍历 ord + 判断高位字节”类自定义函数(如检测 \xC0-\xFF 开头等),在 PHP 8.1 中已无必要:
立即学习“PHP免费学习笔记(深入)”;
- 逻辑复杂,容易漏掉 UTF-8 四字节字符(emoji、生僻字)等边界情况
- 性能远低于
mb_substr(),且无法处理 BOM、代理对等细节 - PHP 8.1 的
mbstring已全面支持 Unicode 14+,覆盖所有常用中文及扩展字符
额外提醒:确保上下文编码统一
即使函数用对了,若源头或输出环节编码混乱,仍可能显示为乱码:
- 文件保存:PHP 源文件本身必须存为 UTF-8 无 BOM 格式
-
HTTP 响应头:输出前建议加
header('Content-Type: text/html; charset=utf-8'); -
数据库连接:若字符串来自 MySQL,需执行
SET NAMES utf8mb4或在 PDO DSN 中指定charset=utf8mb4



















