wordwrap 默认按字节硬切且不识别单词边界,$cut=false仅在有空白时有效,无空白(如长url、中文)时退化为强制截断,易破坏语义或utf-8字符;安全处理需预提取链接并占位,或对中文用mb_substr/preg_split('//u')手动分段。

wordwrap 是 PHP 内置的字符串处理函数,用来按指定宽度折行,但**它不识别单词边界(默认行为)**,容易在单词中间切断。直接用 wordwrap($str, 50) 很可能把 "internationalization" 拆成 "inter\nationali\nzation" —— 这在中文场景下问题不大,但在英文排版或 API 返回格式中常导致可读性下降。
为什么默认 wordwrap 会断词?
因为它的第三个参数 $break 默认是 "\n",而第四个参数 $cut 默认是 false —— 等等,不对:实际默认值是 $cut = false,意思是「不到长度绝不强行截断」,但前提是「有空格」。一旦某行连续字符超过宽度且中间无空格(比如长 URL、邮箱、base64 字符串),$cut = false 就失效,函数会退化为按字节硬切——这正是最常被吐槽的点。
常见错误现象:
输入 "https://example.com/very-long-path-with-no-spaces",设宽度 20,wordwrap 直接从第 20 个字节处劈开,产生非法 URL。
-
$cut = false只在「有空白符可作断点」时才起作用;无空白时,它和$cut = true行为一致 - 中文字符串因无空格分隔,几乎总是触发硬切,所以对中文基本没意义
- PHP 8.1+ 对 Unicode 支持仍有限,
wordwrap按字节计数,不是按字符(mb_wordwrap不存在,得自己封装)
怎么安全地用于英文 + 链接混合文本?
必须开启 $cut = true,并配合预处理:把长链接、邮箱等原子内容替换成占位符,折行后再还原。否则没法兼顾语义与长度限制。
实操建议:
- 先用正则识别并暂存 URL / email:
preg_replace_callback('/https?:\/\/[^\s]+/', ...) - 对剩余文本调用
wordwrap($cleaned, 60, "\n", true) - 最后批量替换回原始链接
- 如果只是日志截断或 CLI 输出,可改用
chunk_split($str, 60, "\n")—— 它严格按长度切,不依赖空格,更可控
中文换行该用什么替代 wordwrap?
别用 wordwrap。中文没有空格分隔,$cut = false 形同虚设,$cut = true 则按字节切,可能把 UTF-8 的多字节字符(如「你好」)劈开,产生乱码。
正确做法是用 mb_substr 手动分段,或借助 preg_split('//u', $str) 拆成字符数组再重组:
function mb_wordwrap($str, $width = 20, $break = "\n") {
$chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
$lines = [];
$line = '';
foreach ($chars as $char) {
if (mb_strlen($line . $char)
<p>注意:这个函数按「Unicode 字符」计数,不是字节;但性能比原生 <code>wordwrap</code> 差,超长文本(>10KB)需谨慎。</p>
<p>真正难的不是调用 <code>wordwrap</code>,而是判断当前文本里有没有 URL、是否含中文、是否要保留 HTML 标签——这些上下文决定了你根本不能只写一行函数就完事。</p>php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











