UTF-8 編碼環境下,中文排序常因編碼規則導致順序錯誤。本文提供 PHP 數組排序與 MySQL 查詢排序兩套成熟方案,核心思路均為「轉為 GBK 編碼排序後再轉回」。
系統默認多為拼音排序,GBK/GB2312 編碼天然符合拼音序,UTF-8 則不符合。
利用 iconv 將 UTF-8 轉 GBK 排序後再轉回:
<?php
/**
* UTF-8 數組按中文拼音排序(保持鍵值關聯)
* @param array &$array 待排序數組(引用傳遞)
* @return bool
*/
function utf8_array_asort(&$array) {
if (!isset($array) || !is_array($array)) {
return false;
}
// UTF-8 -> GBK
foreach ($array as $k => $v) {
$array[$k] = iconv('UTF-8', 'GBK//IGNORE', $v);
}
asort($array); // 排序
// GBK -> UTF-8
foreach ($array as $k => $v) {
$array[$k] = iconv('GBK', 'UTF-8//IGNORE', $v);
}
return true;
}
// 使用示例
$arr = ['張三', '李四', '王五', '趙六'];
utf8_array_asort($arr);
print_r($arr);
// 輸出:Array ( [3] => 趙六 [1] => 李四 [0] => 張三 [2] => 王五 )
?>
ALTER TABLE `mytable` MODIFY `name` CHAR(10) BINARY;
使該字段按二進制比較,間接實現按編碼排序。
./configure --with-charset=gbk --with-extra-charsets=gb2312,gbk
SELECT * FROM `mytable` ORDER BY CONVERT(`chineseColumnName` USING gbk);
優勢:不修改表結構、不重啟服務、兼容現有 UTF-8 數據庫,直接在 SQL 層面解決。
MySQL 默認以 latin1(ISO-8859-1)編譯,字符串比較時不區分大小寫,導致中文雙字節編碼被錯誤拆分比較。CONVERT(... USING gbk) 強制在比較前將字段值按 GBK 解碼,GBK 的字節序恰好符合拼音順序,從而得到正確結果。
//IGNORE 參數忽略無法轉換的字符,防止報錯中斷CONVERT 會導致全表掃描,建議為常排序字段建立功能性索引(MySQL 8.0+ 支持)pinyin 擴展)掌握這兩套方案,徹底解決 UTF-8 環境下中文排序亂序問題。