国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > PHP > 正文

PHP中文字符串截斷無亂碼解決方法

2024-05-04 23:50:51
字體:
來源:轉載
供稿:網友

一個比較好用的字符串截取函數:

function substring($str, $start, $length){ //比較好用字符串截取函數  $len = $length;  if($length < 0){  $str = strrev($str);  $len = -$length;  }  $len= ($len < strlen($str)) ? $len : strlen($str);  $tmpstr = "";  for ($i= $start; $i < $len; $i ++)  {      if (ord(substr($str, $i, 1)) > 0xa0)      {       $tmpstr .= substr($str, $i, 2);       $i++;      } else {       $tmpstr .= substr($str, $i, 1);      }  }  if($length < 0) $tmpstr = strrev($tmpstr);  return $tmpstr;}

使用方法示例:

$str1 = '我是一串比較長的中文不帶英文';$str2 = '我是一串比較長的中文帶yingwen';$len = strlen($str1);echo '<br />'.$len; //return 28$len = strlen($str2);echo '<br />'.$len; //return 29echo '<br />';  echo substring($str1, 0, 11);  echo '<br />';echo substring($str2, 0, 11);    echo '<br />';echo substring($str1, 16, 28);  echo '<br />';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
07null是什么都沒有,而chr(0)的值是0。表示成16進制是0x00,表示成二進制是00000000
08雖然chr(0)不會顯示出什么,但是他是一個字符。
09當漢字被截斷時,根據編碼規則他總是要把后邊的其他字符拉過來一起作為漢字解釋,這就是出現亂碼的原因。而值為0x81到0xff與0x00組合始終都顯示為“空”
10根據這一特點,在substr的結果后面補上一個chr(0),就可以防止出現亂碼了

----------------------------

20120705更新: 

以上方法雖好,但是偶爾還是會碰到亂碼,原因未深究。不過可以用以下的方法,對UTF8字符文本屢試不爽。
注意:該方法中將漢字計算為1單位長度,英文一個字母1單位長度,所以截斷時需要注意長度設置。
計算長度的方法:

function strlen_UTF8($str){  $len = strlen($str);  $n = 0;  for($i = 0; $i < $len; $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;

字符串截斷函數:

function subString_UTF8($str, $start, $lenth)  {    $len = strlen($str);    $r = array();    $n = 0;    $m = 0;    for($i = 0; $i < $len; $i++) {      $x = substr($str, $i, 1);      $a = base_convert(ord($x), 10, 2);      $a = substr('00000000'.$a, -8);      if ($n < $start){        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; }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到PHP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 祁连县| 灌南县| 定结县| 凤阳县| 海门市| 海南省| 淳安县| 区。| 建阳市| 石林| 章丘市| 长乐市| 濉溪县| 塘沽区| 集安市| 丹寨县| 荥阳市| 宁强县| 昆明市| 丽水市| 花莲县| 资阳市| 赫章县| 章丘市| 四会市| 武宣县| 孟连| 垣曲县| 丰县| 固阳县| 余干县| 密云县| 黔西县| 中宁县| 丁青县| 宾阳县| 门头沟区| 宽城| 灵寿县| 灵寿县| 乌苏市|