PHP7.4中截取中文字符串应使用mb_substr等多字节函数,而非substr或iconv+substr组合,因后者按字节操作易乱码;仅当源数据编码不一致时才需先用iconv转码再用mb_substr处理。

直接用 substr 截取含中文的字符串,在 PHP7.4 中极易出乱码,因为 substr 按字节操作,而 UTF-8 下一个汉字占 3 字节。所以“先转码再截取”这个思路本身不准确——关键不是“先转码”,而是**确保在目标编码下按字符而非字节截取**。
为什么不能靠 iconv + substr 组合解决中文截取?
iconv 只负责编码转换,不改变截取逻辑;substr 依然只认字节位置。比如:
-
$str = "你好世界";(UTF-8 编码,共 12 字节) -
iconv("UTF-8", "GBK", $str)→ 得到 GBK 编码字符串(8 字节) -
substr($gbk_str, 0, 4)→ 截前 4 字节,可能切在某个汉字中间,结果仍是乱码
正确做法:用支持多字节的截取函数
PHP7.4 默认启用 mbstring 扩展(推荐开启),应优先使用:
-
mb_substr($str, $start, $length, 'UTF-8')—— 按字符数截取,编码明确,最安全 -
iconv_substr($str, $start, $length, 'UTF-8')—— 依赖 iconv 扩展,功能类似,但兼容性略弱于 mbstring
示例:
$str = "欢迎访问胡文芳的博客!"; echo mb_substr($str, 0, 4, 'UTF-8'); // 输出:欢迎访问
什么时候才需要 iconv 转码?
仅当源数据编码与当前脚本/环境不一致时才需转码,例如:
- 从 GBK 编码的旧数据库或文件读取数据,而你的 PHP 脚本是 UTF-8 环境
- 抓取的网页响应头声明为 GB2312,但内容实际是 UTF-8 或混合编码
此时应:先用 iconv 转成 UTF-8,再用 mb_substr 安全截取:
$raw = file_get_contents('legacy_page.html'); // 假设是 GBK 编码
$utf8 = iconv('GBK', 'UTF-8//IGNORE', $raw);
$result = mb_substr($utf8, 0, 50, 'UTF-8');检查和保障环境基础
避免踩坑,确认以下三点:
- 脚本文件本身保存为 UTF-8 无 BOM 格式
- PHP 配置中
mbstring.func_overload不建议开启(已废弃),优先显式调用mb_*函数 - 用
mb_internal_encoding('UTF-8')或ini_set('default_charset', 'UTF-8')统一内部编码
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











