PHP array_multisort() 可同時對多個陣列或多維陣列的特定鍵進行排序,但原生用法需手動提取排序鍵。本文提供三種封裝函式實作,支援升降序、多鍵排序、型別轉換,並分析效能與適用場景。
array_multisort(array &$array1, mixed $sortOrder = SORT_ASC, mixed $sortFlags = SORT_REGULAR, array &$...): bool
SORT_ASC/SORT_DESC、SORT_REGULAR/SORT_NUMERIC/SORT_STRING。<?php
/**
* 多維陣列指定鍵排序
* @param array $data 待排序陣列(引用修改)
* @param string $key 排序鍵名
* @param int $order SORT_ASC | SORT_DESC
* @param int $flag SORT_REGULAR | SORT_NUMERIC | SORT_STRING
* @return bool
*/
function multiArraySort(array &$data, string $key, int $order = SORT_DESC, int $flag = SORT_REGULAR): bool {
if (empty($data) || !is_array($data)) return false;
$keyArray = [];
foreach ($data as $row) {
if (!is_array($row) || !array_key_exists($key, $row)) {
return false; // 結構不一致
}
$keyArray[] = $row[$key];
}
// array_multisort 會修改 $data 順序
return array_multisort($keyArray, $order, $flag, $data);
}
// === 使用範例 ===
$users = [
['id' => 8, 'name' => 'phpernote', 'score' => 95.5],
['id' => 9, 'name' => 'com', 'score' => 87.2],
['id' => 5, 'name' => 'www', 'score' => 92.1],
];
multiArraySort($users, 'id', SORT_ASC, SORT_NUMERIC);
print_r($users);
// 輸出:id 5, 8, 9 升序
?>
<?php
function arraySortByKey(array $arr, string $key, string $order = 'asc'): array {
$keyValues = [];
foreach ($arr as $k => $v) {
$keyValues[$k] = $v[$key] ?? null;
}
$order === 'asc' ? asort($keyValues) : arsort($keyValues);
$result = [];
foreach ($keyValues as $k => $v) {
$result[] = $arr[$k];
}
return $result;
}
?>
<?php
function arraySortAdvanced(array $array, string $key, string $order = 'asc'): array {
// 1. 參數驗證
if (empty($array) || !is_array($array)) return [];
if ($key === '') return [];
if (!in_array(strtolower($order), ['asc', 'desc'])) return [];
// 2. 提取並清理排序值
$keyValues = [];
foreach ($array as $k => $v) {
if (!is_array($v) || !array_key_exists($key, $v)) continue;
$val = $v[$key];
// 字串清理:移除常見干擾字元
if (is_string($val)) {
$val = str_replace(['-', ' ', ':'], '', $val);
}
$keyValues[$k] = $val;
}
// 3. 排序鍵值陣列(保留索引關聯)
$order === 'asc' ? asort($keyValues) : arsort($keyValues);
// 4. 重建結果
$result = [];
foreach ($keyValues as $k => $v) {
$result[] = $array[$k];
}
return $result;
}
// === 實戰測試 ===
$data = [
['id' => '8', 'date' => '2024-01-15'],
['id' => '9', 'date' => '2024-01-10'],
['id' => '5', 'date' => '2024-01-20'],
];
$sorted = arraySortAdvanced($data, 'id', 'asc');
print_r($sorted);
// id 5, 8, 9 升序(字串數值正確排序)
?>
| 特性 | 實作一 (array_multisort) | 實作二 | 實作三 |
|---|---|---|---|
| 原地修改/回傳新陣列 | 原地修改 (引用) | 回傳新陣列 | 回傳新陣列 |
| 支援排序旗標 | 完整 (NUMERIC/STRING/REGULAR) | 僅字串/數值自動判斷 | 字串清理後自動判斷 |
| 錯誤處理 | 回傳 false | 無 | 參數驗證+跳過無效行 |
| 記憶體效率 | 最高 (無複製) | 中等 | 中等 |
| 適用場景 | 大陣列、需保留引用、多鍵排序 | 簡單快速原型 | 髒資料清洗、API 回應排序 |
<?php
$data = [
['id' => 1, 'score' => 90],
['id' => 2, 'score' => 95],
['id' => 3, 'score' => 90],
];
$score = array_column($data, 'score');
$id = array_column($data, 'id');
// 多陣列傳入 array_multisort:先排 score DESC,再排 id ASC
array_multisort($score, SORT_DESC, SORT_NUMERIC, $id, SORT_ASC, SORT_NUMERIC, $data);
print_r($data);
// 輸出:id 2(95), 1(90), 3(90) → score 同分時 id 小者優先
?>
ORDER BY、usort() 配合快取比較函式、或引入 ds\Vector 等高效資料結構。根據資料規模、髒資料程度、是否需原地修改選擇適當實作,array_multisort() 為核心引擎,封裝層解決工程易用性問題。