如何在多语言环境下实现自然排序(如土耳其语)?

php 的 `natsort()` 不支持按语言规则排序,需改用 `collator` 类并指定本地化区域(如 'tr_tr'),才能正确处理土耳其语等特殊字符的自然排序。

在国际化 Web 应用中,对含非 ASCII 字符(如土耳其语的 Ç, Ş, Ü, Ğ, İ, Ö)的字符串数组进行“自然顺序”排序时,PHP 原生的 natsort() 或 natcasesort() 会失效——因为它们仅基于 ASCII 码值进行轻量级数字感知排序,不理解任何语言的字母表顺序、大小写映射或本地化规则

例如,以下代码看似合理,实则结果错误:

$texts = ["A", "Ü", "Ç", "Ş", "Ğ"];
natcasesort($texts);
print_r($texts);
// 输出顺序不稳定(如 A, Ç, Ü, Ğ, Ş),不符合土耳其语字母表:A, B, C, Ç, D, ..., G, Ğ, ..., Ş, T, U, Ü, V, ...

✅ 正确方案:使用 Collator 类(ICU 国际化库支持)

Collator 是 PHP 提供的符合 Unicode 排序标准(UCA)的多语言排序工具,支持区域设置(locale)、大小写敏感性、数字感知(即“自然排序”)等高级特性。

✅ 示例:按土耳其语规则自然排序

$texts = ["A", "Ü", "Ç", "Ş", "Ğ"];

$collator = new Collator('tr_TR'); // 关键:指定土耳其语区域
$collator->setAttribute(Collator::NUMERIC_COLLATION, Collator::ON); // 启用数字感知(即“自然排序”效果)

if ($collator->sort($texts) === false) {
    throw new RuntimeException('Collator sorting failed: ' . $collator->getErrorMessage());
}

echo implode(', ', $texts); // 输出:A, Ç, Ğ, Ş, Ü ✅ 符合土耳其语字母顺序
? 提示:Collator::NUMERIC_COLLATION 设为 Collator::ON 后,10.txt 会排在 2.txt 之后(类似 natsort 行为),但同时严格遵循 'tr_TR' 的字符权重规则。

⚠️ 注意事项

  • 确保 ICU 扩展启用:Collator 依赖 PHP 的 intl 扩展(通常需启用 extension=intl 并安装 ICU 数据库)。可通过 extension_loaded('intl') 检查。
  • 区域码必须准确:'tr_TR' 表示土耳其语(土耳其),不可简写为 'tr'(部分环境可能回退到默认 locale,导致行为不一致)。
  • 大小写处理:如需忽略大小写,可额外设置:
    $collator->setAttribute(Collator::CASE_LEVEL, Collator::ON); // 启用大小写无关比较(仍保留重音敏感)
    // 或更彻底地:
    $collator->setAttribute(Collator::CASE_FIRST, Collator::LOWER_FIRST); // 小写优先
  • 性能考量:Collator 比 natsort() 开销略高,但对数千条以内数据影响极小;若需极致性能且语言固定,可预生成排序键(如 collator->getSortKey($str)),再用 usort() + 缓存键排序。

✅ 总结

场景 推荐方法
纯 ASCII 数字混合字符串(如文件名 "img2.jpg", "img10.jpg") natsort() 足够
含非英语字符(土耳其语、德语、中文拼音等)的语言合规排序 ✅ 必须用 Collator + 正确 locale
需兼顾自然排序 + 多语言 + 大小写不敏感 Collator 配置 NUMERIC_COLLATION, CASE_LEVEL, ALTERNATE_HANDLING 等属性

正确选择排序工具,是构建国际化应用的基础。告别 natsort 对 Unicode 的“盲目”,拥抱 Collator 的语言智能——让 A, Ç, Ğ, Ş, Ü 成为默认,而非例外。