查詢結果集為二維陣列,需按某欄位(如 id、create_time、score)升序/降序/自然序排序。
/**
* 二維數組按指定鍵排序
* @param array $list 待排序數組(引用傳遞可選)
* @param string $field 排序鍵名
* @param string $sortby 排序類型:asc(升序) | desc(降序) | nat(自然序)
* @return array|false 排序後的新數組,失敗返回 false
*/
function array_sort_by_field(array $list, string $field, string $sortby = 'asc') {
if (empty($list)) return [];
// 建立鍵值映射:索引 => 排序值
$reference = [];
foreach ($list as $key => $row) {
if (!isset($row[$field])) {
trigger_error("Field '{$field}' not exists in row {$key}", E_USER_WARNING);
return false;
}
$reference[$key] = $row[$field];
}
// 根據排序類型選擇排序函數(保持索引關聯)
switch (strtolower($sortby)) {
case 'asc':
asort($reference, SORT_REGULAR);
break;
case 'desc':
arsort($reference, SORT_REGULAR);
break;
case 'nat':
natcasesort($reference);
break;
default:
trigger_error("Invalid sort type: {$sortby}", E_USER_WARNING);
return false;
}
// 按排序後的索引重組數組
$sorted = [];
foreach ($reference as $key => $val) {
$sorted[] = $list[$key];
}
return $sorted;
}
$users = [
['id' => 3, 'name' => 'Charlie', 'score' => 85],
['id' => 1, 'name' => 'Alice', 'score' => 92],
['id' => 4, 'name' => 'David', 'score' => 78],
['id' => 2, 'name' => 'Bob', 'score' => 92],
];
// 按 ID 降序
$sorted = array_sort_by_field($users, 'id', 'desc');
/*
[
['id' => 4, 'name' => 'David', 'score' => 78],
['id' => 3, 'name' => 'Charlie', 'score' => 85],
['id' => 2, 'name' => 'Bob', 'score' => 92],
['id' => 1, 'name' => 'Alice', 'score' => 92],
]
*/
// 按分數降序,同分按 ID 升序(多字段排序需進階函數)
$sorted = array_sort_by_field($users, 'score', 'desc');
/**
* 多字段混合排序
* @param array $list
* @param array $fields ['field1' => 'asc', 'field2' => 'desc', ...]
* @return array
*/
function array_multi_sort(array $list, array $fields) {
if (empty($list) || empty($fields)) return $list;
// 構建比較函數
$cmp = function($a, $b) use ($fields) {
foreach ($fields as $field => $dir) {
$direction = strtolower($dir) === 'desc' ? -1 : 1;
$valA = $a[$field] ?? null;
$valB = $b[$field] ?? null;
if ($valA == $valB) continue;
if ($valA === null) return 1 * $direction;
if ($valB === null) return -1 * $direction;
return $direction * ($valA < $valB ? -1 : 1);
}
return 0;
};
usort($list, $cmp);
return $list;
}
// 使用:先按 score 降序,再按 id 升序
$sorted = array_multi_sort($users, ['score' => 'desc', 'id' => 'asc']);
/*
[
['id' => 1, 'name' => 'Alice', 'score' => 92],
['id' => 2, 'name' => 'Bob', 'score' => 92],
['id' => 3, 'name' => 'Charlie', 'score' => 85],
['id' => 4, 'name' => 'David', 'score' => 78],
]
*/
array_multisortPHP 內建 array_multisort() 功能強大但參數複雜:
$scores = array_column($users, 'score'); $ids = array_column($users, 'id'); // 先按 score 降序,再按 id 升序 array_multisort($scores, SORT_DESC, $ids, SORT_ASC, $users);
| 方案 | 時間複雜度 | 適用場景 | 易用性 |
|---|---|---|---|
array_sort_by_field (asort/arsort) | O(n log n) | 單字段排序、保持關聯索引 | ⭐⭐⭐⭐⭐ |
array_multi_sort (usort) | O(n log n) | 多字段混合排序、自定義比較邏輯 | ⭐⭐⭐⭐ |
array_multisort | O(n log n) | 多字段、需同時排序多個獨立陣列 | ⭐⭐⭐ |
SQL ORDER BY | DB 層優化 | 大數據量、分頁查詢、索引命中 | ⭐⭐⭐⭐⭐ (首選) |
asort/arsort/usort 均為不穩定排序,相同值順序不保證asort/arsort/natcasesort + 索引映射最簡潔高效usort 自定義比較函數最靈活掌握二維數組排序的多種姿勢,能靈活應對報表生成、API 數據整理、搜索結果重排等常見業務場景。