chunk_split() 默认在每段后加\r\n且末尾多加一次,不适用于UTF-8中文(会乱码),应改用mb_substr()循环截取;大文本可转UCS-4优化,但通常mb_substr()已够用。

直接用 chunk_split() 但要注意它默认加 \r\n
chunk_split() 是 PHP 原生函数,专为定长分割设计,但它不是“纯切分”,而是在每段后追加分隔符(默认是 \r\n)。如果你只要等长子串、不要额外字符,它不适用。
- 调用方式:
chunk_split($text, $chunklen, $end),其中$end可自定义,比如设成空字符串''或'|' - 注意:它会在**末尾也补一次**
$end,哪怕最后一段不足$chunklen—— 这是常见误用点 - 它不关心字符编码,对 UTF-8 中文会按字节切,导致乱码;不能用于多字节文本
中文或 UTF-8 文本必须用 mb_substr() 循环截取
处理中文、emoji 或任意 Unicode 文本时,chunk_split() 会崩,得手动按字符数切。核心是用 mb_strlen() 获取真实字符长度,再用 mb_substr() 定长截取。
- 示例逻辑:
$chunks = []; for ($i = 0; $i < mb_strlen($text, 'UTF-8'); $i += $len) { $chunks[] = mb_substr($text, $i, $len, 'UTF-8'); } - 务必显式传入
'UTF-8'编码参数,否则在某些环境(如旧版 Windows)下mb_*函数可能失效 - 如果
$len为 0 或负数,mb_substr()返回空或 false,需提前校验
需要保留完整词/不打断单词?得结合 str_word_count() 或正则
纯按长度切可能把一个词从中间劈开(比如 “hello-world” 在第 5 位切,变成 “hello” + “-world”)。若业务要求语义完整,就不能硬切。
- 简单策略:先用
str_word_count($text, 1)拆出词数组,再累积拼接,直到超长就切一刀 - 更稳方案:用正则
/(.{1,$len})(?:\s+|$)/u匹配“最多$len字符 + 后跟空白或结尾”,但需测试边界情况(如连续标点、无空格长串) - 注意:中文没有天然空格分词,此法对纯中文效果有限,此时更适合按句号、换行等标点做预分割
性能敏感场景别用 mb_substr() 频繁调用
当文本超长(如 >1MB)、分块数上千时,反复调用 mb_substr() 会有明显开销,因为每次都要重新扫描编码位置。
立即学习“PHP免费学习笔记(深入)”;
- 优化方向:改用
mb_convert_encoding()转成 UCS-4(每个字符固定 4 字节),再用普通substr()切,最后转回 UTF-8 —— 但代码变重,只在极端场景值得 - 更实际的权衡:如果只是日志分段或 API 响应拆包,用
mb_substr()循环完全够用;真卡顿时,先确认是不是 IO 或网络成了瓶颈,而非切分本身 - 别忘了:
mb_internal_encoding('UTF-8')设全局编码可省略部分参数,但不推荐——显式传参更可控
实际用哪一种,取决于你手上的文本是否含中文、是否允许断词、以及量级有多大。最容易被忽略的是:默认的 chunk_split() 对中文无效,且末尾多塞一次分隔符——这两点在线上出过不少 bug。










