首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 多維數組按指定字段排序:array_multisort 封裝通用函數 sortArrByField

     編輯:PHP 相關知識

需求背景

從數據庫查詢或 API 獲取的列表數據通常為多維數組,需按某字段 (如 price, created_at, sort_order) 升序/降序排列。PHP 內置 array_multisort 功能強大但調用繁瑣,本文封裝一個通用單行調用函數。

通用排序函數

<?php
/**
 * 多維數組按字段排序 (原地修改)
 * @param array  $array  待排序數組 (引用)
 * @param string $field  排序字段名
 * @param bool   $desc   true=降序, false=升序 (默認)
 */
function sortArrByField(array &$array, string $field, bool $desc = false): void {
    if (empty($array)) return;
    $fieldArr = array_column($array, $field); // PHP 5.5+ 專用,比 foreach 快
    $sortFlag = $desc ? SORT_DESC : SORT_ASC;
    array_multisort($fieldArr, $sortFlag, $array);
}
?>

使用示例

<?php
$products = [
    ['id'=>1, 'name'=>'A', 'price'=> 299, 'sales'=> 100],
    ['id'=>2, 'name'=>'B', 'price'=> 199, 'sales'=> 500],
    ['id'=>3, 'name'=>'C', 'price'=> 399, 'sales'=> 50],
];

// 價格升序
sortArrByField($products, 'price');
/* 結果: B(199), A(299), C(399) */

// 銷量降序
sortArrByField($products, 'sales', true);
/* 結果: B(500), A(100), C(50) */

// 多字段排序:先按銷量降序,銷量相同再按價格升序
$field1 = array_column($products, 'sales');
$field2 = array_column($products, 'price');
array_multisort($field1, SORT_DESC, $field2, SORT_ASC, $products);
?>

進階:支持多字段、自定義比較、保持鍵名

<?php
/**
 * 增強版:支持多字段、自定義排序標誌、自然排序、保持鍵名
 */
function multisort(array &$array, array $specs, int $flags = SORT_REGULAR): void {
    if (empty($array)) return;
    $args = [];
    foreach ($specs as $spec) {
        // $spec = ['field'=>'price', 'order'=>SORT_DESC, 'flags'=>SORT_NUMERIC]
        $field = $spec['field'];
        $order = $spec['order'] ?? SORT_ASC;
        $flag  = $spec['flags'] ?? $flags;
        $args[] = array_column($array, $field);
        $args[] = $order;
        $args[] = $flag;
    }
    $args[] = &$array; // 最後傳入原數組引用
    array_multisort(...$args);
}

// 使用
multisort($products, [
    ['field'=>'sales', 'order'=>SORT_DESC, 'flags'=>SORT_NUMERIC],
    ['field'=>'price', 'order'=>SORT_ASC,  'flags'=>SORT_NUMERIC],
]);
?>

常見坑點與避坑指南

問題原因解決
排序後數字鍵名重置為 0,1,2...array_multisort 默認重置數字索引傳入關聯數組 (字符串鍵) 或排序前保存鍵名後恢復
字符串數字 "100" < "20" (字典序)默認 SORT_STRING指定 SORT_NUMERIC 標誌
字段值包含 null/不存在array_column 返回 null,排序靠前預處理填充默認值,或過濾後再合併
大數組性能差array_column + array_multisort 需複製內存數據量 > 10萬 建議在 SQL ORDER BY 或 Redis ZSET 排序

現代框架中的等效操作

// Laravel Collection
$products->sortBy('price')->values()->all();           // 升序
$products->sortByDesc('sales')->values()->all();       // 降序
$products->sortBy([['sales','desc'], ['price','asc']]); // 多字段

// Symfony
use Symfony\Component\PropertyAccess\PropertyAccessor;
// 或使用 usort + 閉包比較器

總結

sortArrByField 以 3 行核心代碼解決 90% 單字段排序需求,配合 array_column (PHP 5.5+) 代碼極其簡潔高效。複雜多字段排序直接調用 array_multisort 或使用框架 Collection 方法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved