首頁 >後端開發 >php教程 >php中文字串截斷且無亂碼的解決方法

php中文字串截斷且無亂碼的解決方法

WBOY
WBOY原創
2016-07-25 09:07:24835瀏覽
  1. function substring($str, $start, $length){ //比較好用字串截取函數
  2. $len = $ length;
  3. if($length $str = strrev($str);
  4. $len = -$length;
  5. }
  6. $len= ($len $tmpstr = "";
  7. for ($i= $start; $i {
  8. if (ord(substr($str, $i, 1)) > 0xa0)
  9. {
  10. $tmpstr .= substr($str, $i, 2);
  11. $i++;
  12. } else {
  13. $tmpstr .= substr($str, $i, 1);
  14. }
  15. }
  16. if($length return $tmpstr;
  17. }
  18. ?>
複製程式碼

使用方法範例:

  1. $str1 = '我是一串較長的中文不帶英文';

  2. $str2 = '我是一串比較長的中文帶yingwen';
  3. $len = strlen($str1);

  4. echo '
    '.$len; / /return 28
  5. $len = strlen($str2);

  6. echo '
    '.$len; //return 29
  7. echo '
    ';

  8. echo substring($str1, 0, 11);
  9. echo '
    ';
  10. echo substring($str2, 0, 11);
  11. echo '
    ';
  12. echo substring($str1, 16, 28);
  13. echo '
    ';
  14. echo substring($str2, 16, 29);
  15. echo substring($str2, 16, 29); ?>
複製程式碼

結果顯示: 28 29 我是一串比較 我是一串比較 中文不帶英文 中文帶yingwen

這個函數十分有用,例如用來截斷比較長的檔名,但是要在中間加上...,可以這樣來做:

  1. function formatName($str, $size){
  2. $len = strlen($str);
  3. if (strlen($str) > $size) {
  4. $part1 = substring($str, 0, $size / 2);
  5. $part2 = substring($str, $len - ($size/2) , $len);
  6. return $part1 . "..." . $part2;
  7. } else {
  8. return $str;
  9. }
  10. }
  11. ?>
複製程式碼

另外,網路上看到一種超級簡單的中文截斷解決方案,經過測試,效果很不錯:

  1. echo substr($str1,0,10).chr(0);
  2. ?>
複製程式碼

原理解釋: chr(0)不是null null是什麼都沒有,而chr(0)的值是0。表示成16進位是0x00,表示成二進位是00000000 雖然chr(0)不會顯示出什麼,但是他是一個字元。 當漢字被截斷時,根據編碼規則他總是要把後邊的其他字符拉過來一起作為漢字解釋,這就是出現亂碼的原因。而值為0x81到0xff與0x00組合總是顯示為“空” 根據這個特點,在substr的結果後面補上一個chr(0),就可以防止出現亂碼了

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

  1. function strlen_UTF8($str)

  2. {
  3. $len = strlen($str );
  4. $n = 0;
  5. for($i = 0; $i $x = substr($str, $i, 1);
  6. $a = base_convert(ord($x), 10, 2);
  7. $a = substr('00000000'.$a, -8);
  8. if (substr($a, 0, 1) = = 0) {
  9. }elseif (substr($a, 0, 3) == 110) {
  10. $i += 1;
  11. }elseif (substr($a, 0, 4) == 1110) {
  12. $i += 2;
  13. }
  14. $n++;
  15. }
  16. return $n;
  17. } // End strlen_UTF8;
  18. } // End strlen_UTF8;
  19. ///字串截斷函數:
  20. function subString_UTF8($str, $start, $lenth)
  21. {
  22. $len = strlen($str);
  23. $r = array() ;
  24. $n = 0;
  25. $m = 0;
  26. for($i = 0; $i $x = substr($str, $i , 1);
  27. $a = base_convert(ord($x), 10, 2);
  28. $a = substr('00000000'.$a, -8);
  29. if ($n if (substr($a, 0, 1) == 0) {
  30. }elseif (substr($a, 0, 3) == 110) {
  31. $i += 1;
  32. }elseif (substr($a, 0, 4) == 1110) {
  33. $i += 2;
  34. }
  35. $n++;
  36. }else{
  37. if (substr($a, 0, 1) == 0) {
  38. $r[ ] = substr($str, $i, 1);
  39. }elseif (substr($a, 0, 3) == 110) {
  40. $r[ ] = substr($str, $i, 2);
  41. $i += 1;
  42. }elseif (substr($a, 0, 4) == 1110) {
  43. $r[ ] = substr($str, $i, 3);
  44. $i += 2;
  45. }else{
  46. $r[ ] = '';
  47. }
  48. if (++$m >= $lenth){
  49. break;
  50. }
  51. }
  52. }
  53. return join($r);
  54. } // End subString_UTF8;
  55. //使用方法和之前介紹的一樣,例如formatName可以實作如下(這對漢字長度做了小優化):

  56. function formatName($str, $size ){
  57. $len = strlen_UTF8($str);
  58. $one_len = strlen($str);
  59. $size = $size * 1.5 * $len / ($one_len);
  60. if( strlen_UTF8($str) > $size) {
  61. $part1 = subString_UTF8($str, 0, $size / 2);
  62. $part2 = subString_UTF8($str, $len - ($size/2), $len);
  63. return $part1 . "..." . $part2;
  64. } else {
  65. return $str;
  66. }
  67. }
?>
複製程式碼



陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn