1. 程式人生 > >PHP的strtolower()和strtoupper()函式在安裝非中文系統的伺服器下可能會導致將漢字轉換為亂碼,請寫兩個替代的函式實現相容Unicode文字的字串大小寫轉換

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碼都不屬於英文字元,不會被轉換。