近日接手一個二開添加翻譯插件的任務(wù),加翻譯插件前網(wǎng)頁顯示正常,加插件后部分網(wǎng)頁前部顯示正常,后部顯示亂碼,看起來與文本編碼不正確差不多。一開始感覺有些無從下手,仔細瀏覽網(wǎng)頁后發(fā)現(xiàn),每次出現(xiàn)亂碼前都有個不完整的文字,懷疑是文字截取錯誤造成了亂碼。
打開源碼,發(fā)現(xiàn)原代碼中使用了substr函數(shù)來截取字符串。在php中,substr函數(shù)是嚴格按字節(jié)數(shù)來截取字符串,雖然一個中文字符為3個字節(jié),如果僅以3的倍數(shù)來進行截取,字符串中一旦出現(xiàn)字母、數(shù)字等單字節(jié)字符而沒有在截取前進行判斷處理,就很容易造成出現(xiàn)截取到半個中文字符的情況。
例如如下代碼,
$str=”活潑楓葉6c的頭條號”;echo substr($str,0,15);
運行的結(jié)果為
活潑楓葉6c
雖然截取的15個字符,因為6c兩個字符只占2個字節(jié),打亂了字符串的規(guī)律,所以結(jié)果會出現(xiàn)半個字符。
說到這里,可能有些小伙伴會想在截取前先對字符串進行一下處理,或者自己寫一個函數(shù)。其實大可不必這么麻煩,php已經(jīng)為我們提供了解決方案。
1、按字符數(shù)量截取字符串的mb_substr
例如
$str=”活潑楓葉6c的頭條號”;echo mb_substr($str,0,7);
運行的結(jié)果為
活潑楓葉6c的
需要截取幾個字,參數(shù)就寫幾個字,一目了然。
2、按字節(jié)截取字符串的mb_strcut
例如
$str=”活潑楓葉6c的頭條號”;echo mb_strcut($str,0,15);
運行結(jié)果為
活潑楓葉6c
可以看到,雖然mb_strcut也是按字節(jié)截取字符串,但它不會截斷字符。
在PHP中,substr雖然用得很多,但要對中文字符串進行截取時,應(yīng)根據(jù)需要選擇mb_substr或mb_strcut,從而避免出現(xiàn)半個字符亂碼的情況。