PHP的strtolower()和strtoupper()函式在安裝非中文系統的伺服器下可能會導致將漢字轉換為亂碼,請寫兩個替代的函式實現相容Unicode文字的字串大小寫轉換
阿新 • • 發佈:2019-01-04
最近看到一個比較有意思的問題,如題。
首先檢視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碼都不屬於英文字元,不會被轉換。