Tips:PHP中截取中文字符串避免乱码

2010 一月 11
tags: , ,
by Luin

使用substr截取中文字符串可能会出现意外的乱码,而不同编码下中文字符串长度是不同的,特殊情况比较多。下面的csubstr()函数是我在开发博客巢系统时编写的,它用了一个小方法:strlen(‘汉’)比较取巧的解决了这个问题。

(2010-01-23:根据Gill的回复似乎这样做并不稳妥,回来再好好研究研究,有更好的方法欢迎与我交流)

/*截取字符串(避免中文乱码)*/
function csubstr($string,$sublength) {
	$len = strlen($string);
	if ($len <= $sublength){
		$string = $string;
	}else{
		$string = substr($string,0,$sublength);
		$parity= 0;
		for($j=0;$j<$sublength;$j++){
			$temp_str=substr($string,$j,1);
				if(Ord($temp_str)>127) $parity+=1;
		}
		$n = $parity % strlen('汉');
		if($n == 0) {
			$string=substr($string,0,$sublength);
		} else {
			$string=substr($string,0,$sublength - $n);
		}
	}
	return $string;
}

更新:可以在设定编码的前提下使用mb_substr避免乱码:

string mb_substr ( string $str , int $start [, int $length [, string $encoding ]] )

详见:http://php.net/manual/en/function.mb-substr.php

感谢Gill的回复

相关日志

3 Responses leave one →
  1. Gill permalink
    一月 12, 2010

    不同编码下中文字符串长度是不同的,strlen返回的是字符串编码长度,mb_strlen返回的是字符个数,mb_substr截取一定的字符数,不会有乱码问题。从实用上看,需要用编码长度来精确截取字符串的场景并不多。截取字符串主要用在数据库存储和页面字符串定长显示。MySQL里VARCHAR(10)能存10个汉字,不需要考虑字条串编码长度问题。而无论是使用编码长度还是字符个数,都不太好控制字符串的显示长度。

    • Luin permalink*
      一月 13, 2010

      当时查到了这个函数但是觉得还要设置编码所以才自己写了一个,不过现在看起来mb_substr显得更方便些:-)。写这个是用于“页面字符串定长显示”的,不过只要求大致显示长度一致就可以了,所以只考虑编码长度就可以了~~

  2. Gill permalink
    一月 14, 2010

    UTF-8是变长的,汉字所占的编码长度不一样,strlen(‘汉’)并不适用于所有的汉字。

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS