PHP 提供豐富的陣列排序函式,針對「值排序」、「鍵名排序」、「保持索引關聯」等不同需求有專屬函式。本文透過實戰範例,系統整理 usort、uksort、sort 等核心函式的用法與比較函式撰寫技巧。
| 函式 | 排序對象 | 是否保持鍵名關聯 | 適用場景 |
|---|---|---|---|
sort() | 值 | 否(重建 0..n 索引) | 單純數值/字串陣列,不需保留原鍵名 |
usort() | 值(自訂比較) | 否 | 複雜物件、多欄位排序、自訂邏輯 |
uksort() | 鍵名(自訂比較) | 是 | 關聯式陣列需按鍵名自訂排序 |
asort() | 值 | 是 | 關聯式陣列按值排序且保留鍵名 |
ksort() | 鍵名 | 是 | 關聯式陣列按鍵名正序排序 |
所有 u* 系列函式的回呼函式必須回傳 整數:
< 0:第一個參數 小於 第二個 → 排在前面= 0:相等 → 順序未定義(PHP 4.1.0+ 不保證穩定性)> 0:第一個參數 大於 第二個 → 排在後面// 標準寫法:太空船運算子 (PHP 7+)
function cmp($a, $b) {
return $a <=> $b; // 升序;降序用 $b <=> $a
}
// 相容 PHP 5.x 寫法
function cmp($a, $b) {
if ($a == $b) return 0;
return ($a > $b) ? 1 : -1; // 升序
}
$numbers = [3, 2, 5, 6, 1];
usort($numbers, function($a, $b) {
return $b <=> $a; // 降序
});
// 結果:[6, 5, 3, 2, 1]
print_r($numbers);
$data = [
4 => 'four',
3 => 'three',
20 => 'twenty',
10 => 'ten',
];
uksort($data, function($a, $b) {
return $a <=> $b; // 鍵名升序
});
/* 結果:
Array
(
[3] => three
[4] => four
[10] => ten
[20] => twenty
)
*/
print_r($data);
$fruits = ['lemon', 'orange', 'banana', 'apple'];
sort($fruits); // 字母升序,索引重建為 0,1,2,3
/* 結果:
Array
(
[0] => apple
[1] => banana
[2] => lemon
[3] => orange
)
*/
print_r($fruits);
$users = [
['name'=>'Alice', 'age'=>25, 'score'=>90],
['name'=>'Bob', 'age'=>20, 'score'=>95],
['name'=>'Carol', 'age'=>25, 'score'=>85],
];
// 先按 age 升序,再按 score 降序
$age = array_column($users, 'age');
$score = array_column($users, 'score');
array_multisort($age, SORT_ASC, $score, SORT_DESC, $users);
print_r($users);
array_map 建立輔助陣列,再配合 array_multisort。usort 等函式已改用穩定排序演算法(Timsort),相等元素順序會保持;但官方文件仍建議「不依賴穩定性」。ORDER BY 或專門的搜尋引擎(Elasticsearch)。掌握 usort/uksort/sort 的差異與比較函式撰寫規範,即可靈活應對各種陣列排序需求。現代 PHP 專案建議優先使用 太空船運算子 <=> 簡化比較邏輯,配合 array_multisort 處理多維多欄位排序,程式碼更簡潔且效能更佳。