在 PHP 中,国际化的功能非常丰富,包括很多我们可能都不知道的东西其实都非常有用,比如说今天要介绍的这一系列的字符排序和比较的功能。
排序正常来说,如果我们对数组中的字符进行排序,按照的是字符的 ASC2 表的顺序进行排列,如果是英文还好,但对于中文的话,排序出来的结果会是非常懵逼的。
$arr = ['我','是','硬','核','项', '目', '经', '理']; sort($arr); var_dump( $arr ); // array(8) { // [0]=> // string(3) "我" // [1]=> // string(3) "是" // [2]=> // string(3) "核" // [3]=> // string(3) "理" // [4]=> // string(3) "目" // [5]=> // string(3) "硬" // [6]=> // string(3) "经" // [7]=> // string(3) "项" // }
按照我们的习惯会以中文的拼音来对汉字进行排序,这个时候往往大家都会选择自己写排序的算法或者去找合适的 Composer 包。其实,PHP 中已经为我们准备了一个对象就是用来处理这类问题的。
$coll = new Collator( 'zh_CN' ); $coll->sort($arr); var_dump( $arr ); // array(8) { // [0]=> // string(3) "核" // [1]=> // string(3) "经" // [2]=> // string(3) "理" // [3]=> // string(3) "目" // [4]=> // string(3) "是" // [5]=> // string(3) "我" // [6]=> // string(3) "项" // [7]=> // string(3) "硬" // }
没错,正是这个 Collator 类。它在实例化的时候需要指定当前的区域,比如我们指定为 zh_CN ,也就是中文字符区域,这时候再使用它的 sort() 方法就可以完成对中文字符的拼音排序。
$coll->sort($arr, Collator::SORT_NUMERIC ); var_dump( $arr ); // array(8) { // [0]=> // string(3) "核" // [1]=> // string(3) "经" // [2]=> // string(3) "理" // [3]=> // string(3) "目" // [4]=> // string(3) "是" // [5]=> // string(3) "我" // [6]=> // string(3) "项" // [7]=> // string(3) "硬" // } $coll->sort($arr, Collator::SORT_STRING ); var_dump( $arr ); // array(8) { // [0]=> // string(3) "核" // [1]=> // string(3) "经" // [2]=> // string(3) "理" // [3]=> // string(3) "目" // [4]=> // string(3) "是" // [5]=> // string(3) "我" // [6]=> // string(3) "项" // [7]=> // string(3) "硬" // }
Collator 对象的 sort() 方法还支持第二个参数,用于指定当前的排序是按照字符还是数字格式进行排序。对于纯中文的内容来说,这个没有什么区别。
除了 sort() 方法之外,它还有一个 asort() 方法,就和普通的 asort() 函数一样的功能,只不过它也是支持不同的区域语言的。
$arr = [ 'a' => '100', 'b' => '7', 'c' => '50' ]; $coll->asort($arr, Collator::SORT_NUMERIC ); var_dump( $arr ); // array(3) { // ["b"]=> // string(1) "7" // ["c"]=> // string(2) "50" // ["a"]=> // string(3) "100" // } $coll->asort($arr, Collator::SORT_STRING ); var_dump( $arr ); // array(3) { // ["a"]=> // string(3) "100" // ["c"]=> // string(2) "50" // ["b"]=> // string(1) "7" // } $arr = [ '中' => '100', '的' => '7', '文' => '50' ]; $coll->asort($arr, Collator::SORT_NUMERIC ); var_dump( $arr ); // array ( // '的' => '7', // '文' => '50', // '中' => '100', // ) $coll->asort($arr, Collator::SORT_STRING ); var_dump( $arr ); // array ( // '中' => '100', // '文' => '50', // '的' => '7', // )
asrot() 方法是根据键和值一起进行排序的,所以在这里指定 SORT_STRING 和 SORT_NUMERIC 就有明显的效果了。我们可以看出,如果是根据数字排序,那么结果就是以数字内容为准的,如果是根据字符排序,那么结果就是以键值中的字符串部分为基础进行排序的。
不管是 sort() 还是 asrot() 本质上都和普通的 PHP 默认提供的 sort() 和 asrot() 函数一样的。只是它们多了区域语言的功能而已。
另外,Collator 对象中还提供了一个 sortWithSortKeys() 方法,这个是普通的 PHP 排序函数中没有的。
$arr = ['我','是','硬','核','项', '目', '经', '理']; $coll->sortWithSortKeys($arr); var_dump( $arr ); // array ( // 0 => '核', // 1 => '经', // 2 => '理', // 3 => '目', // 4 => '是', // 5 => '我', // 6 => '项', // 7 => '硬', // )
它与 sort() 方法是类似的,但使用的是 ucol_getSortKey() 来生成的 ICU 排序键,在大型数组上的速度更快。
ICU 的全称是 International Components for Unicode ,也就是 Unicode 的国际化组件,它提供了翻译相关的功能,也就是我们系统中以及各类编程语言要实现国际化能力的基础。
比较接下来就是字符串的比较,比如说我们都知道,"a" 是比 "A" 要大的,因为在 ASC2 码表中,"A" 是 65 ,"a" 是 97 。当然,这只是默认情况下的比较,在使用 Collator 对象的函数进行比较时,则是根据字典库中的排序索引进行比较的,对于中文来说,基本上就也是按照拼音的顺序来比较了。
var_dump($coll->compare('Hello', 'hello')); // int(1) var_dump($coll->compare('你好', '您好')); // int(-1)