PHP的strtolower()和strtoupper()函数在安装非中文系统的服务器下可能会导致将汉字转换为乱码,请写两个替代的函数实现兼容Unicode文字的字符串大小写转换

最近看到一个比较有意思的问题,如题。
首先查看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)