星期四, 5月 15, 2008

UTF-8與php計算字串長度的函數

UTF-8是一種可變長度Unicode編碼。使用一至四個bytes作為文字的編碼:

1. 128 個 US-ASCII 文字只需一個byte編碼。
2. 拉丁文、希臘文、亞美尼亞語、希伯來文、阿拉伯文、敘利亞文、
斯拉夫文等特殊拼音文字需要二個bytes編碼。
3. 東亞地區文字,包涵正體中文(繁體中文)、簡體中文、日文、
韓文使用三個bytes編碼。
4. 其他特殊文字則使用四個bytes編碼。


在php中常見的計算字串長度的函數有:strlen和mb_strlen,
讓我們來看在utf-8環境內會有什麼不同結果。
為了避免Blog誤判,所以這裡捨棄網頁的語法,只列出php的語法區塊。
<?php
$str='中文測試abc123';
echo 'strlen「中文測試abc123」為'.strlen($str)."<hr>";
echo 'mb_strlen「中文測試abc123」為'.mb_strlen($str,'utf8')."<hr>";
$str2='RussiaРосси́я';
echo 'strlen「RussiaРосси́я」為'.strlen($str2)."<hr>";
echo 'mb_strlen「RussiaРосси́я」為'.mb_strlen($str2,'utf8')."<hr>";
?>
輸出結果為:
strlen「中文測試abc123」為18
mb_strlen「中文測試abc123」為10
strlen「RussiaРосси́я」為20
mb_strlen「RussiaРосси́я」為13

這裡我們可以看到strlen在計算字串長度時,會依據文字類型來判斷,
中文字每一個字視為3 bytes,而斯拉夫文每一個字視為2 bytes,
所以「中文測試」這幾個字長度為3*4=12,而「Росси́я」
(斯拉夫文裡的俄羅斯)這幾個字則為2*7=14。
所以$str長度為12+6=18,而$str2長度為6+14=20

而mb_strlen在計算字串長度時,
會將一個中文字或特殊拼音文字視為長度1,
所以「中文測試」這幾個字長度為4,
而「Росси́я」(斯拉夫文裡的俄羅斯)這幾個字則為7。
所以$str長度為4+6=10,而$str2長度為6+7=13。

參考資料:
http://en.wikipedia.org/wiki/UTF-8
http://tools.ietf.org/html/rfc3629

沒有留言:

張貼留言