在PHP中,国际化的函数非常丰富,包括很多我们可能不知道其实非常有用的东西,比如一系列的字符排序和比较函数。排序是正常的。如果我们对数组中的字符进行排序,它们将按照字符的ASC2表的顺序排列。如果是英文还好,中文的话排序结果会很混乱。$arr=['I','is','hard','core','item','mesh','jing','reason'];sort($arr);var_dump($arr);//array(8){//[0]=>//string(3)"I"//[1]=>//string(3)"Yes"//[2]=>//string(3)"core"//[3]=>//string(3)"reason"//[4]=>//string(3)"mesh"//[5]=>//string(3)"hard"//[6]=>//string(3)"jing"//[7]=>//string(3)"item"//}按照我们的习惯,我们会用汉语拼音来进行汉字排序,这时候人们往往会选择自己写排序算法或者找一个合适的Composer包。其实PHP已经为我们准备了一个对象来处理这类问题。$coll=newCollat??or('zh_CN');$coll->sort($arr);var_dump($arr);//array(8){//[0]=>//string(3)"核心"//[1]=>//string(3)"jing"//[2]=>//string(3)"reason"//[3]=>//string(3)"mesh"//[4]=>//string(3)"Yes"//[5]=>//string(3)"I"//[6]=>//string(3)"Item"//[7]=>//string(3)"hard"//}是的,就是这个Collat??or类。实例化时需要指定当前区域。比如我们指定zh_CN,就是汉字区。这时候使用它的sort()方法就可以完成汉字的拼音排序。$coll->sort($arr,Collat??or::SORT_NUMERIC);var_dump($arr);//array(8){//[0]=>//string(3)"core"//[1]=>//string(3)"jing"//[2]=>//string(3)"reason"//[3]=>//string(3)"mesh"//[4]=>//string(3)"Yes"//[5]=>//string(3)"I"//[6]=>//string(3)"Item"//[7]=>//string(3)"hard"//}$coll->sort($arr,Collat??or::SORT_STRING);var_dump($arr);//数组(8){//[0]=>//字符串(3)"Core"//[1]=>//string(3)"Jing"//[2]=>//string(3)"Li"//[3]=>//string(3)"Object"//[4]=>//string(3)"Yes"//[5]=>//string(3)"I"//[6]=>//string(3)"Item"//[7]=>//string(3)"hard"//}Collat??or对象的sort()方法还支持第二个参数,用于指定当前排序是按字符排序还是按数字排序格式。对于纯中文内容,这没有区别。除了sort()方法之外,它还有一个asort()方法,和普通的asort()函数功能一样,只是还支持不同的地区语言。$arr=['a'=>'100','b'=>'7','c'=>'50'];$coll->asort($arr,Collat??or::SORT_NUMERIC);var_dump($arr);//数组(3){//["b"]=>//字符串(1)"7"//["c"]=>//字符串(2)"50"//["a"]=>//string(3)"100"//}$coll->asort($arr,Collat??or::SORT_STRING);var_dump($arr);//array(3){//["a"]=>//字符串(3)"100"//["c"]=>//字符串(2)"50"//["b"]=>//字符串(1)"7"//}$arr=['中'=>'100','S'=>'7','文'=>'50'];$coll->asort($arr,Collat??or::SORT_NUMERIC);var_dump($arr);//数组(//'of'=>'7',//'文'=>'50',//'中'=>'100',//)$coll->asort($arr,Collat??or::SORT_STRING);var_dump($arr);//数组(//'in'=>'100',//'text'=>'50',//'of'=>'7',//)asrot()方法是根据key和value进行排序,所以这里指定SORT_STRING和SORT_NUMERIC效果明显。我们可以看到,如果是按数字排序,结果是按照数字内容排序,如果是按字符排序,结果是按照键值中的字符串部分排序。sort()和asrot()与普通PHP默认提供的sort()和asrot()函数本质上是一样的。只是他们的地方语言功能比较多。此外,Collat??or对象还提供了一个sortWithSortKeys()方法,这是普通PHP排序函数所没有的。$arr=['I','is','hard','core','items','mesh','by','reason'];$coll->sortWithSortKeys($arr);var_dump($arr);//array(//0=>'nucleus',//1=>'jing',//2=>'reason',//3=>'mesh',//4=>'yes',//5=>'I',//6=>'Item',//7=>'Hard',//)它类似于sort()方法,但是使用ucol_getSortKey()来生成ICU排序键,在大型数组上速度更快。ICU的全称是InternationalComponentsforUnicode,是Unicode的国际化组件。它提供了翻译相关的功能,是我们系统和各种编程语言实现国际化能力的基础。比较的下一步是字符串的比较。比如我们都知道“a”比“A”大,因为在ASC2码表中,“A”是65,“a”是97。当然这只是默认的比较。当使用Collat??or对象的功能进行比较时,比较是基于字典库中的排序索引。对于中文来说,基本上是按照拼音的顺序来比较的。var_dump($coll->compare('你好','你好'));//int(1)var_dump($coll->compare('Hello','Hello'));//int(-1)compare()方法用于比较。如果两个字符串相等,则返回0。如果第一个字符串大于第二个字符串,则返回1,否则返回-1。从代码中可以看出,“Hello”大于“hello”,“Hello”小于“Hello”(因为“you”多了一个g)。属性设置Collat??or对象也可以设置一些对象属性。$coll->setAttribute(Collat??or::CASE_FIRST,Collat??or::UPPER_FIRST);var_dump($coll->getAttribute(Collat??or::CASE_FIRST));//int(25)var_dump($coll->compare('Hello','hello'));//int(-1)$coll->setAttribute(Collat??or::CASE_FIRST,Collat??or::LOWER_FIRST);var_dump($coll->getAttribute(Collat??or::CASE_FIRST));//int(24)var_dump($coll->compare('Hello','hello'));//int(1)$coll->setAttribute(Collat??or::CASE_FIRST,Collat??or::OFF);var_dump($coll->getAttribute(Collat??or::CASE_FIRST));//int(16)var_dump($coll->compare('Hello','hello'));//int(1)这里我们为对象指定了CASE_FIRST属性,属性值可以指定大写优先,小写优先等,对于英文字符,这会影响排序比较的结果。另外,我们还可以通过一个方法获取当前区域语言的信息。var_dump($coll->getLocale(Locale::VALID_LOCALE));//string(10)"zh_Hans_CN"var_dump($coll->getLocale(Locale::ACTUAL_LOCALE));//string(2)"zh"第一个参数分别获取有效区域信息和实际区域信息。排序信息当然,我们还可以看到具体的排序信息,即Collat??or中字符的编码。var_dump(bin2hex($coll->getSortKey('Hello')));//string(20)"b6b0bebec4010901dc08"var_dump(bin2hex($coll->getSortKey('hello')));//string(18)"b6b0bebec401090109"var_dump(bin2hex($coll->getSortKey('Hello')));//string(16)"7b9b657301060106"var_dump(bin2hex($coll->getSortKey('Hello')));//字符串(16)"7c33657301060106"$coll=collat??or_create('en_US');var_dump($coll->compare('Hello','hello'));//int(1)var_dump($coll->compare('你还好','你好'));//int(-1)var_dump($coll->getLocale(Locale::VALID_LOCALE));//string(5)"en_US"var_dump($coll->getLocale(Locale::ACTUAL_LOCALE));//string(4)"root"var_dump(bin2hex($coll->getSortKey('Hello')));//字符串(20)"3832404046010901dc08"var_dump(bin2hex($coll->getSortKey('hello')));//字符串(18)"383240404601090109"var_dump(bin2hex($coll->getSortKey('Hello')));//string(20)"fb0b8efb649401060106"var_dump(bin2hex($coll->getSortKey('Hello')));//string(20)"fba5f8fb649401060106"可以看到,不要用一样的getSortKey()获取的排序键信息对于不同的地区语言是不同的,但是都是以16进制存储的,与默认的ASC2码完全不同。错误信息$coll=newCollat??or('en_US');;$coll->compare('y','k');var_dump($coll->getErrorCode());//int(0)var_dump($coll->getErrorMessage());//string(12)"U_ZERO_ERROR"使用getErrorCode()获取错误代码,使用getErrorMessage()获取错误信息。关于返回的U_ZERO_ERROR,没有查到相关资料。希望有知识的朋友能够回复,让我们一起学习。排序规则强度另外,Collat??or对象也有排序强度设置,但是我测试的效果没有体现出来。$arr=array('a','à','A');$coll=newCollat??or('de_DE');$coll->sort($arr);var_dump($coll->getStrength());var_dump($arr);//int(2)//array(3){//[0]=>//string(1)"a"//[1]=>//string(1)"A"//[2]=>//string(2)"à"//}$coll->setStrength(Collat??or::IDENTICAL);var_dump($coll->getStrength());//int(15)$coll->sort($arr);var_dump($arr);$coll->setStrength(Collat??or::QUATERNARY);var_dump($coll->getStrength());//int(3)$coll->sort($arr);var_dump($arr);$coll->setStrength(Collat??or::PRIMARY);var_dump($coll->getStrength());//int(0)$coll->sort($arr);var_dump($arr);$coll->setStrength(Collat??or::TERTIARY);var_dump($coll->getStrength());//int(2)$coll->sort($arr);var_dump($arr);$coll->setStrength(Collat??or::SECONDARY);var_dump($coll->getStrength());//int(1)$coll->sort($arr);var_dump($arr);在官方文档中测试代码的结果中,指定不同的参数会返回不同的排序顺序,但是我实际测试的结果都是一样的。所以这里就不解释了,因为没看懂为什么。每个人都可以理解。有知道这方面知识的朋友欢迎留言回复一起学习!让我们总结一个有趣的对象。其实这个对象也支持面向过程的函数编写,示例代码中也有面向过程的调用。总的来说,拼音排序和比较这两个功能相信在实际开发中是有很大潜力的。你可以试试看!测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202011/source/3.PHP.php中的国际化字符串比较对象参考文档:https://www.php.net/manual/zh/class.collat??or.php各媒体平台均可搜索【硬核项目经理】
