我看到很多實際應用中,人們依賴這個函式來將字串截斷到給定的長度,並在結尾附加一些字元,就像上面文件中的範例 #1 一樣。
雖然這在西方字母中運作良好,但應該注意的是,字串的寬度不一定與其長度相同。
在中文、日文和韓文中,某些字元可以表示為全形或半形,這可能會導致非預期的結果...
<?php
$str = ['英文' => '瑞士',
'半形' => 'スイス',
'全形' => 'スイス',
];
foreach ($str as $w => $s) {
printf("%-10s: %s (位元組=%d 字元數=%d 寬度=%d)\n子字串: %s\n修剪寬度: %s\n\n",
$w, $s,
strlen($s), mb_strlen($s), mb_strwidth($s),
mb_substr($s, 0, 3),
mb_strimwidth($s, 0, 3)
);
}
/* 輸出
# 使用 ASCII 時,字元數 == 寬度,所以一切如預期
英文 : 瑞士 (位元組=6 字元數=2 寬度=2)
子字串: 瑞士
修剪寬度: 瑞士
# 使用半形片假名時,也一樣
半形 : スイス (位元組=9 字元數=3 寬度=3)
子字串: スイス
修剪寬度: スイス
# 全形片假名的寬度是兩倍,所以我們只得到第一個「ス」!
全形 : スイス (位元組=9 字元數=3 寬度=6)
子字串: スイス
修剪寬度: ス
*/
>?