Tips:PHP中截取中文字符串避免乱码
2010 一月 11
使用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 →
不同编码下中文字符串长度是不同的,strlen返回的是字符串编码长度,mb_strlen返回的是字符个数,mb_substr截取一定的字符数,不会有乱码问题。从实用上看,需要用编码长度来精确截取字符串的场景并不多。截取字符串主要用在数据库存储和页面字符串定长显示。MySQL里VARCHAR(10)能存10个汉字,不需要考虑字条串编码长度问题。而无论是使用编码长度还是字符个数,都不太好控制字符串的显示长度。
当时查到了这个函数但是觉得还要设置编码所以才自己写了一个,不过现在看起来mb_substr显得更方便些:-)。写这个是用于“页面字符串定长显示”的,不过只要求大致显示长度一致就可以了,所以只考虑编码长度就可以了~~
UTF-8是变长的,汉字所占的编码长度不一样,strlen(‘汉’)并不适用于所有的汉字。