PHP 內建 substr() 按位元組截取,對多位元組編碼(GBK/UTF-8)會導致中文斷碼、亂碼。需依編碼特性實作字元級截取。
0xA0) { // 中文區間
if ($charCount >= $start) {
$result .= $str[$i] . $str[$i+1];
}
$i++; // 跳過第二位元組
$charCount++;
} else { // ASCII
if ($charCount >= $start) {
$result .= $str[$i];
}
$charCount++;
}
}
return $result;
}
?>
$sublen) {
return implode('', array_slice($chars, $start, $sublen)) . '...';
}
return implode('', array_slice($chars, $start, $sublen));
} else { // GB2312/GBK
$start *= 2; $sublen *= 2; // 近似位元組位移
$strlen = strlen($string);
$result = '';
for ($i = 0; $i < $strlen; $i++) {
if ($i >= $start && $i < $start + $sublen) {
$ord = ord($string[$i]);
if ($ord > 129) { // 中文首位元組
$result .= $string[$i] . $string[$i+1];
$i++;
} else {
$result .= $string[$i];
}
}
if (ord($string[$i]) > 129) $i++;
}
return strlen($result) < $strlen ? $result . '...' : $result;
}
}
// 使用範例
$str = "abcd需要截取的字符串";
echo cutStr($str, 8, 0, 'GB2312'); // 輸出:abcd需要截取
?>
= 224) { // 3 位元組 UTF-8
$result .= substr($string, $i, 3);
$i += 3;
} elseif ($ord >= 192) { // 2 位元組 UTF-8
$result .= substr($string, $i, 2);
$i += 2;
} else { // ASCII
$result .= $char;
$i++;
}
}
return $append ? $result . '...' : $result;
}
?>
建議:生產環境優先使用 mb_substr()、mb_strimwidth(),僅在無法安裝擴展時使用自製函數。