我看到很多实际应用中,人们依赖此函数将字符串截断到给定长度并在末尾附加一些字符,例如上面文档中的示例 #1。
虽然这在西方字母中运行良好,但需要注意的是,字符串的宽度不一定与其长度相同。
在中文、日文和韩文中,某些字符可以表示为全角或半角,这可能会导致意外结果……
<?php
$str = ['English' => 'Switzerland',
'Half width' => 'スイス',
'Full width' => 'スイス',
];
foreach ($str as $w => $s) {
printf("%-10s: %s (bytes=%d chars=%d width=%d)\nSubstring : %s\nTrim width: %s\n\n",
$w, $s,
strlen($s), mb_strlen($s), mb_strwidth($s),
mb_substr($s, 0, 3),
mb_strimwidth($s, 0, 3)
);
}
/* 输出
# 使用 ASCII,字符 == 宽度,因此一切按预期工作
English : Switzerland (bytes=11 chars=11 width=11)
Substring : Swi
Trim width: Swi
# 使用半角片假名,它也工作
Half width: スイス (bytes=9 chars=3 width=3)
Substring : スイス
Trim width: スイス
# 全角片假名是两倍宽,所以我们只得到第一个 'su'!
Full width: スイス (bytes=9 chars=3 width=6)
Substring : スイス
Trim width: ス
*/
>?