array_multisort 本质是对多个数组同步重排,按参数从左到右优先级递减排序:先依首数组定序,相等时用次数组区分,最终所有数组按同一索引顺序重排。

array_multisort 并不直接“按字段排序多维数组”,它本质是**对多个数组(或数组的列)进行同步排序**,而“按字段”只是我们通过提取列、构造辅助数组的方式达成的效果。它的底层执行流程不是黑箱,而是清晰分步的数组重排过程。
核心机制:先比对,再统一重排
array_multisort 不是逐个元素调用比较函数去冒泡或快排,而是:
- 把每个传入的数组(或引用)视为一个“排序维度”,按从左到右顺序优先级递减;
- 先根据第一个数组的值确定最终元素的相对位置(即主排序依据);
- 当第一个数组中出现相等值时,才用第二个数组的对应位置值进一步区分(次级排序);
- 依此类推,直到所有维度用尽或顺序已完全确定;
- 最后,**所有输入数组按第一个数组决定的索引顺序,同步重排**——这才是“同步”的关键:不是只排一个,而是所有数组都按同一套新下标重新组织。
“按字段排序”的实际操作步骤
对多维数组(如 $data = [['name'=>'B','age'=>25], ['name'=>'A','age'=>30]])按 'age' 升序,典型写法是:
$ages = array_column($data, 'age'); array_multisort($ages, SORT_ASC, $data);
这背后发生的是:
- 提取出一维辅助数组 $ages = [25, 30];
- array_multisort 发现 $ages 升序排列后索引不变(0→0, 1→1),所以 $data 保持原序;
- 若 $ages 是 [30, 25],排序后逻辑位置变为 [25,30],对应原索引 [1,0],于是 $data 索引也被强制重排为 [$data[1], $data[0]];
- 如果还传了 $names = array_column($data, 'name'),并写成
array_multisort($ages, SORT_ASC, $names, SORT_ASC, $data),就变成先按 age 排,age 相同时再按 name 字典序排。
重要细节:传参必须是变量,且可被修改
array_multisort 要求所有数组参数都是**变量(非表达式)**,因为它会直接修改这些变量的内容:
- 不能写
array_multisort(array_column($data,'age'), $data)—— 第一个参数不是变量,会报 Warning; - 它不是返回新数组,而是就地修改所有传入的数组变量;
- 如果某个数组长度比其他短,PHP 会用 0 或空字符串补位参与比较(可能引发意外结果),所以务必保证维度对齐。
和 usort 的根本区别
usort 对单个数组内部元素做比较回调,每次 compare 函数接收两个完整子数组,逻辑灵活但无法天然支持多级稳定排序(需手动实现);array_multisort 则依赖多个独立数组的数值映射,排序逻辑由 PHP 内部 C 实现的快速排序变种完成,效率更高,且天然支持多字段稳定排序,但前提是能提前把字段抽成平行的一维数组。

















