PHP usort()函数的使用方法
使用usort()函数可以以用户自定义的排序规则对数据进行排序., 其定义为
bool usort ( array &$array , callable $value_compare_func )
usort()函数的返回值类型为bool 布尔型, 排序成功返回true,否则返回false
usort()函数有两个参数, 第一个参数为array(数组)类型,且是一个引用数组, 你需要把要排序的数据以数组的形式作为第一个参数传递给usort()函数
第二个参数为callable(可调用)类型, 你需要把排序方式写成一个比较函数, 并将函数名称传递给usort()的第二个参数
比较函数 $value_compare_func通过比较数组元素的值来排序该数组, 如经比较后两个数组元素的值相等, 那么它们两如何排序是未知的.
当排序时usort()函数会将数组元素原有的键名删除并赋予新的键名。而不是仅仅将键名重新排序
如数组 $arr = array(3,1,2); 其键值对应关系为
0 => 3
1 => 1
2 => 2
如让usort()按升序排序,其对应关系为
0 => 1
1 => 2
2 => 3
而非将键名重新排序
1 => 1
2 => 2
0 => 3
usort()函数的第二个参数的比较函数是一个callback回调函数(返回一个值用来回复调用它的函数) 其定义为int callback ( mixed $a, mixed $b )
这个回调函数的返回值必须是一个int整型值(在PHP 7.0.0版本之前这个整型值的取值范围是-2147483648 到 2147483647), 这个用于比较的回调函数的两个参数都是混合型值(整型、浮点型、对象、数组够可以), 当要按照升序排序时, $a>$b 要返回大于0的整型值, $a==$b要返回0, $a<$b要返回小于0的整型值, 如果是降序排序, $a>$b 要返回小于0的整型值, $a=$b要返回0, $a<$b要返回大于0的整型值。
用usort()排序示例
用usort()进行简单排序
<?php
$a = array(17, 5, 83, 9, 62);
//声明一个叫做cmp的函数, cmp是 compare的缩写,是比较的意思function cmp($a, $b){ if ($a > $b) { return 1; } else if ($a < $b) {
return -1;
} else if ($a == $b) {
return 0;
}}//让usort使用cmp回调函数对数组$a进行升序排序usort($a, "cmp"); foreach ($a as $key => $value) { echo "$key => $value\n";}?>
排序结果为
0 => 5
1 => 9
2 => 17
3 => 62
4 => 83

使用usort对多维数组进行排序
<?php
function cmp($a, $b)
{
//strcmp是string compare 字符串比较的缩写,
//用来比较两个字符串大小
//$a,$b用来接收数组第一维,如 $a = $cities[0]
return strcmp($a["city"], $b["city"]);
}
//创建一个二维数组
$cities[0]["city"] = "shanghai";
$cities[1]["city"] = "beijing";
$cities[2]["city"] = "tianjin";
$cities[3]['city'] = 'chongqing';
usort($cities, "cmp");
print_r($cities); //输出二维数组$cities的值
?>
print_r的显示结果为
Array ( [0] => Array ( [city] => beijing ) [1] => Array ( [city] => chongqing ) [2] => Array ( [city] => shanghai ) [3] => Array ( [city] => tianjin ) )
,可知4个城市名称已经按字母的升序进行了排序, 即
$cities[0]['city'] => beijing
$cities[0]['city'] => chongqing
$cities[0]['city'] => shanghai
$cities[0]['city'] => tianjin

把类的静态方法或者对象的方法当成一个回调函数传递给usort()
<?php
//先声明一个要排序的数组
$arr = array('y', 'z', 'x');
class obj {
//定义一个用于比较的静态方法cmp_method,其用于升序排序
static function cmp_method ($a, $b) {
if ($a>$b) {
return 1;
} else if ($a<$b) {
return -1;
} else {
return 0;
}
}
//定义一个用于比较的非静态方法cmp_method2, 其用于降序排序
function cmp_method2 ($a, $b) {
if ($a>$b) {
return -1;
} else if ($a<$b) {
return 1;
} else {
return 0;
}
}
}
//把一个类的静态方法传递给usort()需要使用数组形式,
//数组的第一个元素是类的名字,第二个参数是静态方法的名字
usort($arr, array('obj', 'cmp_method'));
print_r($arr);
其输出结果为Array (
[0] => x
[1] => y
[2] => z
), 即把数组$arr进行了升序排序
//把类obj实例化为对象$obj
$obj = new obj();
//把对象的非静态方法传递给usort()参数也需要使用数组形式,
//数组的第一个元素是对象变量$obj, 第二个参数是非静态方法的名字
usort($arr, array($obj, 'cmp_method2'));
print_r($arr);
其输出结果为
Array
(
[0] => z
[1] => y
[2] => x
)
, 即把数组$arr进行了降序排序

使用一个闭包(closure)去排序多维数组
<?php
//以城市和GDP排名声明一个二维数组
$array[0] = array('gdp' => '1', 'city' => 'Shanghai');
$array[1] = array('gdp' => '2', 'city' => 'Beijing');
$array[2] = array('gdp' => '3', 'city' => 'Guangzhou');
function sorter($key) {
//匿名函数使用use引用外部函数sorter的参数从而形成闭包
return function ($a, $b) use ($key) {
//按照字母自然顺序排序, 字母升序
return strnatcmp($a[$key], $b[$key]);
};
}
//当usort()第二个参数调用了build_sorter函数后,
//build_sorter()函数返回其内部的匿名函数,
//该匿名函数还引用了build_sorter()传入的参数$key
usort($array, sorter('city')); //这是以第二维的第二个元素为排序标准
foreach ($array as $item) {
echo $item['city'], '的GPD排名是第', $item['gdp'], '<br>';
}
?>
输出结果为, 按照城市字母的升序进行了排序
Beijing的GPD排名是第2
Guangzhou的GPD排名是第3
Shanghai的GPD排名是第1

PHP7新特性,宇宙飞船操作符简化usort()书写过程
PHP7新增了一个宇宙飞船操作符(spaceship operator), 它可以简化回调函数的返回部分,从而简化usort()函数的书写过程
比较两个数的大小时写做 $a <=> $b , 该运算时有三种结果, 当左边大于右边返回1, 左边小于右边返回-1, 两边相等返回0,
如果需要降序结果, 直接在前面加上负号, 取反即可, 如 -($a<=>$b), 如下代码
<?php
$arr = [8,72,56,43,992,278,453,26];//等同于array(8,72,56,43,992,278,453,26)
//asc是ascend的缩写, 表示升序
$asc = $arr;
//其中<=>是宇宙飞船操作符,
//该操作符左边的数若大于右边的数就返回1
//若该操作符左边的数小于右边的数则返回-1
//若该操作符两边的数相等则返回0
usort($asc, function($a, $b) {return ($a<=>$b);});
print_r($asc);
//desc是descend的缩写, 降序的意思
$desc = $asc;
//如需要降序结果, 则只需在使用<=>的表达式左边加上负号
usort($desc, function($a, $b) {return -($a<=>$b);});
print_r($desc);


注意事项
回调函数返回的整型值的取值范围是在PHP7.0之前是-2147483648 到 2147483647,PHP7.0之后是
如果从用于比较的回调函数返回一个非整型值,比如一个float浮点值,这个浮点值会被内部转换为回调函数所规定必须要要返回的整型值,比如返回浮点值0.8和0.3, 这两个浮点值都会被转换自己的整数部分,即0, 0.8和0.3都会被转换成0, 所以0.8和0.3的比较结果是相等的。