最近看到一个比较有意思的问题,如题。
首先查看php函数的实现源码,以strtolower为例,源码如下
c = (unsigned char *)s;e = c+len;// 遍历s,逐个变为小写while (c < e) {*c = tolower(*c);c++;}return s;
tolower函数
int tolower(int c) { if ((c >= 'A') && (c <= 'Z')) return c + ('a' - 'A'); return c; }
可见在转换某些区分大小写的汉字编码(如utf8)的时候会导致问题
具体解法如下:
function str_toupper($str){if(!is_string($str)){return $str;}$strOut = '';$strArr = str_split($str,1);foreach($strArr as $val){if(ord($val) >= ord('a') && ord($val) <= ord('z')){ $strAsc = ord($val);$strAsc += ord('A') - ord('a'); $val = chr($strAsc);}$strOut .= $val;}return $strOut;}
function str_tolower($str){if(!is_string($str)){return $str;}$strOut = '';$strArr = str_split($str,1);foreach($strArr as $val){if(ord($val) >= ord('A') && ord($val) <= ord('Z')){ $strAsc = ord($val);$strAsc += ord('a') - ord('A'); $val = chr($strAsc);}$strOut .= $val;}return $strOut;}
实现大小写转换仍用变换asc II码来实现,在遍历的时候替换成str_split,该字符分割函数是按字节来分割,汉字会被分成3个字节,每个字节的asc II码都不属于英文字符,不会被转换。
PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码 请写两个替代的函数实现兼容Unicode文字的字符串大小写转换