`array_multisort()` 是 PHP 排序多個陣列或多維陣列的利器,支援混合排序順序與類型。本文詳細拆解參數語法、排序標誌組合、鍵名保留行為,並給出二維陣列多欄位排序最佳實踐。
array_multisort(array &$array1, mixed $array1_sort_order = SORT_ASC, mixed $array1_sort_flags = SORT_REGULAR, mixed ...$rest): bool
| 分類 | 常量 | 說明 |
|---|---|---|
| 順序 | SORT_ASC | 升序 (預設) |
| SORT_DESC | 降序 | |
| 類型 | SORT_REGULAR | 常規比較 (不轉型,預設) |
| SORT_NUMERIC | 數值比較 | |
| SORT_STRING | 字串比較 (區分大小寫,大寫優先) | |
| SORT_NATURAL | 自然排序 (如 "img2" < "img10") | |
| SORT_FLAG_CASE | 配合 SORT_STRING/NATURAL 忽略大小寫 |
規則:每個陣列後只能跟一個順序標誌 + 一個類型標誌。標誌僅對緊前的陣列生效,預設 `SORT_ASC | SORT_REGULAR`。
$users = [
['id' => 3, 'name' => 'Alice', 'age' => 25],
['id' => 1, 'name' => 'Bob', 'age' => 28],
['id' => 2, 'name' => 'Alice', 'age' => 22],
['id' => 4, 'name' => 'Charlie','age' => 25],
];
// 需求:id 降序、name 升序、age 升序
// 1. 提取排序欄位
$ids = array_column($users, 'id');
$names = array_column($users, 'name');
$ages = array_column($users, 'age');
// 2. 多重排序 (最後一個參數必須是原資料陣列)
array_multisort(
$ids, SORT_DESC, SORT_NUMERIC, // id 降序、數值比較
$names, SORT_ASC, SORT_STRING, // name 升序、字串比較
$ages, SORT_ASC, SORT_NUMERIC, // age 升序、數值比較
$users // 原陣列跟著重排
);
print_r($users);
Array
(
[0] => Array ( [id] => 4 [name] => Charlie [age] => 25 )
[1] => Array ( [id] => 3 [name] => Alice [age] => 25 )
[2] => Array ( [id] => 2 [name] => Alice [age] => 22 )
[3] => Array ( [id] => 1 [name] => Bob [age] => 28 )
)
$data = [
'a' => ['score' => 90],
'b' => ['score' => 95],
'c' => ['score' => 90],
];
// 使用 array_multisort 會重置數字鍵,字串鍵保留
$scores = array_column($data, 'score');
array_multisort($scores, SORT_DESC, $data);
// 結果鍵仍為 a,b,c
$files = ['img1.png', 'img10.png', 'Img2.png', 'img20.png'];
array_multisort($files, SORT_ASC, SORT_NATURAL | SORT_FLAG_CASE);
// 結果:['img1.png', 'Img2.png', 'img10.png', 'img20.png']
class User { public $id; public $name; }
$users = [new User(3,'C'), new User(1,'A'), new User(2,'B')];
$ids = array_map(fn($u) => $u->id, $users);
array_multisort($ids, SORT_ASC, $users);
usort($users, function($a, $b) {
// 先按角色權重排,再按 id
$roleWeight = ['admin'=>3, 'editor'=>2, 'user'=>1];
$diff = ($roleWeight[$b->role] ?? 0) - ($roleWeight[$a->role] ?? 0);
return $diff ?: $a->id - $b->id;
});
| 錯誤 | 原因 | 修正 |
|---|---|---|
| Warning: Array sizes are inconsistent | 參與排序的陣列長度不一致 | 確保所有陣列 (含原資料) 元素數量相同 |
| 排序結果不符預期 | 字串比較 "10" < "2" | 加 `SORT_NUMERIC` 或 `SORT_NATURAL` |
| 大小寫順序錯亂 | SORT_STRING 大寫優先 | 加 `SORT_FLAG_CASE` 忽略大小寫 |
| 原陣列未變化 | 忘記傳址 (&) 或參數順序錯 | 最後一個參數必須是原陣列變數 |
一句話精髓:提取欄位 → 組合標誌 → 最後傳原陣列,記住「字串鍵保留、數字鍵重索引、標誌只管前一個陣列」。