PHP中文数组排序需用Collator类按拼音排序,因默认sort()按字节序导致乱序;需启用intl扩展,设置locale为'zh_CN'后调用asort()即可正确排序并保留键名。

PHP 中文数组排序的关键不是“中文”本身,而是字符串比较时的编码和 locale 设置。默认的 sort()、asort() 等函数按字节序(ASCII)比较,对 UTF-8 中文会乱序(比如“张”在“李”前还是后完全取决于 Unicode 码点,而非拼音或笔画),所以不能直接用。
中文按拼音排序:用 collator 类(推荐)
collator 类(推荐)PHP 内置的 Collator 支持 ICU 排序规则,能正确处理中文拼音顺序(需启用 intl 扩展)。
- 确保
intl已启用:extension=intl在 php.ini 中未被注释 - 使用
Collator::SORT_REGULAR+setLocale('zh')或'zh_CN'
示例:
$names = ['张三', '李四', '王五', '阿飞'];
$collator = new Collator('zh_CN');
$collator->asort($names);
print_r($names); // 输出:['阿飞', '李四', '王五', '张三'](按拼音 a-l-w-z)
注意:
-
Collator::asort()会修改原数组,且保留键名(类似asort()) - 若传入关联数组(如
['id1' => '张三', 'id2' => '李四']),仍可用$collator->asort($arr) - 不支持 PHP
中文按拼音排序:用 array_multisort() + strcoll()
array_multisort() + strcoll()
如果无法启用 intl,可退而求其次,用系统 locale 配合 strcoll() ——但必须先设置中文 locale(Linux/macOS 通常支持 zh_CN.UTF-8,Windows 需用 Chinese_China.936 或类似,不稳定)。
步骤:
- 调用
setlocale(LC_COLLATE, 'zh_CN.UTF-8')(失败则 fallback) - 用
array_map('strcoll', $arr, array_fill(0, count($arr), ''))不行 ——strcoll是二元比较,不能直接映射 - 正确做法是配合
usort():
setlocale(LC_COLLATE, 'zh_CN.UTF-8') ?: setlocale(LC_COLLATE, 'Chinese_China.936');
usort($names, function($a, $b) {
return strcoll($a, $b);
});
风险点:
- 不同服务器 locale 名称差异大,
setlocale()可能返回false,导致回退到字节序排序 - Windows 下 UTF-8 locale 支持弱,容易失效
-
strcoll()对空值、null、非字符串类型敏感,需提前过滤
中文按 Unicode 码点排序(不推荐,但最稳定)
如果你只要“固定顺序”,不追求拼音逻辑,且数组全是标准 UTF-8 中文,可强制转为 Unicode 码点序列再排序:
做法是用 mb_convert_encoding($str, 'UCS-4LE', 'UTF-8') 得到 4 字节二进制,再 unpack('V', ...) 提取首字符码点 ——但太重,一般没必要。
更实用的妥协方案:
- 用
iconv('UTF-8', 'GB2312//IGNORE', $str)转成 GB2312 编码(拼音大致有序),再sort()——仅限简体中文,且有乱码风险 - 预生成拼音首字母映射表(如
['张'=>'zhang', '李'=>'li']),用usort()比较拼音字段 ——适合小规模、可控数据
真正麻烦的不是“怎么排”,而是“为什么排出来不对”。绝大多数中文排序出错,根源是没意识到 PHP 默认根本不认识“中文顺序”,它只认字节。用 Collator 是目前最可靠、最无需 hack 的路径,但前提是 intl 扩展开着——检查 php -m | grep intl,没输出就去装。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











