-
-
function substring($str, $start, $length){ //比較好用字串截取函數
- $len = $ length;
- if($length $str = strrev($str);
- $len = -$length;
- }
- $len= ($len $tmpstr = "";
- for ($i= $start; $i {
- if (ord(substr($str, $i, 1)) > 0xa0)
- {
- $tmpstr .= substr($str, $i, 2);
- $i++;
- } else {
- $tmpstr .= substr($str, $i, 1);
- }
- }
- if($length return $tmpstr;
- }
- ?>
複製程式碼
使用方法範例:
-
-
$str1 = '我是一串較長的中文不帶英文';
- $str2 = '我是一串比較長的中文帶yingwen';
$len = strlen($str1);
- echo '
'.$len; / /return 28
$len = strlen($str2);
- echo '
'.$len; //return 29
echo ' ';
- echo substring($str1, 0, 11);
- echo '
';
- echo substring($str2, 0, 11);
- echo '
';
- echo substring($str1, 16, 28);
- echo '
';
- echo substring($str2, 16, 29);
- echo substring($str2, 16, 29); ?>
-
-
複製程式碼
結果顯示:
28
29
我是一串比較
我是一串比較
中文不帶英文
中文帶yingwen
這個函數十分有用,例如用來截斷比較長的檔名,但是要在中間加上...,可以這樣來做:
-
-
function formatName($str, $size){
- $len = strlen($str);
- if (strlen($str) > $size) {
- $part1 = substring($str, 0, $size / 2);
- $part2 = substring($str, $len - ($size/2) , $len);
- return $part1 . "..." . $part2;
- } else {
- return $str;
- }
- }
- ?>
-
複製程式碼
另外,網路上看到一種超級簡單的中文截斷解決方案,經過測試,效果很不錯:
-
-
echo substr($str1,0,10).chr(0);
- ?>
-
複製程式碼
原理解釋:
chr(0)不是null
null是什麼都沒有,而chr(0)的值是0。表示成16進位是0x00,表示成二進位是00000000
雖然chr(0)不會顯示出什麼,但是他是一個字元。
當漢字被截斷時,根據編碼規則他總是要把後邊的其他字符拉過來一起作為漢字解釋,這就是出現亂碼的原因。而值為0x81到0xff與0x00組合總是顯示為“空”
根據這個特點,在substr的結果後面補上一個chr(0),就可以防止出現亂碼了
20120705更新:
以上方法雖好,但偶爾還是會碰到亂碼,原因未深究。不過可以用以下的方法,對UTF8字元文字屢試不爽。
注意:此方法中將漢字計算為1單位長度,英文一個字母1單位長度,所以截斷時需注意長度設定。
計算長度的方法:
-
-
function strlen_UTF8($str)
- {
- $len = strlen($str );
- $n = 0;
- for($i = 0; $i $x = substr($str, $i, 1);
- $a = base_convert(ord($x), 10, 2);
- $a = substr('00000000'.$a, -8);
- if (substr($a, 0, 1) = = 0) {
- }elseif (substr($a, 0, 3) == 110) {
- $i += 1;
- }elseif (substr($a, 0, 4) == 1110) {
- $i += 2;
- }
- $n++;
- }
- return $n;
- } // End strlen_UTF8;
-
- } // End strlen_UTF8;
- ///字串截斷函數:
- function subString_UTF8($str, $start, $lenth)
- {
- $len = strlen($str);
- $r = array() ;
- $n = 0;
- $m = 0;
- for($i = 0; $i $x = substr($str, $i , 1);
- $a = base_convert(ord($x), 10, 2);
- $a = substr('00000000'.$a, -8);
- if ($n if (substr($a, 0, 1) == 0) {
- }elseif (substr($a, 0, 3) == 110) {
- $i += 1;
- }elseif (substr($a, 0, 4) == 1110) {
- $i += 2;
- }
- $n++;
- }else{
- if (substr($a, 0, 1) == 0) {
- $r[ ] = substr($str, $i, 1);
- }elseif (substr($a, 0, 3) == 110) {
- $r[ ] = substr($str, $i, 2);
- $i += 1;
- }elseif (substr($a, 0, 4) == 1110) {
- $r[ ] = substr($str, $i, 3);
- $i += 2;
- }else{
- $r[ ] = '';
- }
- if (++$m >= $lenth){
- break;
- }
- }
- }
- return join($r);
- } // End subString_UTF8;
//使用方法和之前介紹的一樣,例如formatName可以實作如下(這對漢字長度做了小優化):
- function formatName($str, $size ){
- $len = strlen_UTF8($str);
- $one_len = strlen($str);
- $size = $size * 1.5 * $len / ($one_len);
- if( strlen_UTF8($str) > $size) {
- $part1 = subString_UTF8($str, 0, $size / 2);
- $part2 = subString_UTF8($str, $len - ($size/2), $len);
- return $part1 . "..." . $part2;
- } else {
- return $str;
- }
- }
?>
複製程式碼
|