wordwrap() 默认按字节截断导致中文乱码,因其不支持 utf-8 多字节字符;应使用 mb_wordwrap() 等多字节函数按字符处理,或预处理标点后谨慎使用原函数。

PHP 的 wordwrap() 函数默认按**字节**计数,而中文字符(UTF-8 编码下)通常占 3 字节。当设置 $width = 20 时,它可能在某个中文字符中间切断,导致乱码或显示异常——这不是“换行失败”,而是编码感知缺失造成的截断。
根本原因:wordwrap 不识别多字节字符
该函数是面向单字节字符(如 ASCII)设计的,对 UTF-8 中文无内置支持。即使字符串本身是合法 UTF-8,wordwrap() 仍会从字节流角度切分,破坏字符完整性。
推荐解决方案:用 mb_ 系列函数替代
使用 PHP 的多字节字符串函数,确保按“字符”而非“字节”计算宽度:
-
用
mb_substr()+ 手动扫描实现安全换行:逐字符累加宽度,遇到空格/标点或超限时在前一位置断开 -
封装一个支持中文的
mb_wordwrap(),例如:
php
function mb_wordwrap($str, $width = 75, $break = "\n", $cut = false) {
if (empty($str) || $width $result = [];
$len = mb_strlen($str, 'UTF-8');
$start = 0;
while ($start $end = $start + $width;
if ($end >= $len) {
$result[] = mb_substr($str, $start, null, 'UTF-8');
break;
}
if (!$cut) {
// 向左找最近的空白或标点(常见中文断行点)
$safeEnd = mb_strrpos(mb_substr($str, $start, $width, 'UTF-8'), ' ', MB_CASE_FOLD, 'UTF-8');
if ($safeEnd === false) {
$safeEnd = mb_strrpos(mb_substr($str, $start, $width, 'UTF-8'), ',', MB_CASE_FOLD, 'UTF-8');
}
if ($safeEnd !== false) {
$end = $start + $safeEnd;
}
}
$result[] = trim(mb_substr($str, $start, $end - $start, 'UTF-8'));
$start = $end;
}
return implode($break, $result);
}
?>
更轻量的临时方案:预处理 + wordwrap
若只需避免乱码、不强求语义断行点,可先用空格替换中文标点(如顿号、逗号、句号),再调用原生 wordwrap():
$clean = preg_replace('/[,。!?;:""''()【】《》、]/u', ' ', $text);$wrapped = wordwrap($clean, $width, "\n", false);- 再把空格还原为原标点(需记录位置,较复杂,仅适合简单场景)
注意:不要依赖 cut_long_words = true
设 $cut = true 会让 wordwrap() 强制截断,但仍是按字节切,中文依然会碎成乱码。这个参数只对英文长单词安全,对中文无效且危险。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











