From PHP5.6, you can use a variadic technique. Simply push all of your sorting data and sorting logic into an indexed array, then use the splat operator to unpack the parameters into array_multisort()
. Be sure to make the array that you wish to modify -- modifiable by reference before pushing it into the parameters array.
The pushing of parameters into $sortingParams
below can be written more succinctly as a single declaration, but I think it will be easier to conceptualize this way. These individual pushes would be suitable inside of an iterating process (e.g. foreach()
).
For every column of data used to sort the parent array, you may elect to push zero, one, or two additional elements to best signify the sorting logic.
Code: (Demo)
$array = [
['number' => 2, 'letter' => 'a', 'price' => 9.99],
['number' => 3, 'letter' => 'b', 'price' => 9.99],
['number' => 1, 'letter' => 'c', 'price' => 9.50],
['number' => 1, 'letter' => 'd', 'price' => 10],
['number' => 1, 'letter' => 'e', 'price' => 9.99],
];
$sortingParams[] = array_column($array, 'number'); // 1-dimensional
$sortingParams[] = SORT_ASC; // this is omittable as well because it is assumed (just for demo)
$sortingParams[] = array_column($array, 'price'); // 1-dimensional
$sortingParams[] = SORT_DESC;
$sortingParams[] = SORT_NUMERIC; // this is omittable as well because it is assumed (just for demo)
$sortingParams[] = &$array; // this is the actual master array which should be modified
array_multisort(...$sortingParams); // unpack with splat operator
var_export($array);
Output:
array (
0 =>
array (
'number' => 1,
'letter' => 'd',
'price' => 10,
),
1 =>
array (
'number' => 1,
'letter' => 'e',
'price' => 9.99,
),
2 =>
array (
'number' => 1,
'letter' => 'c',
'price' => 9.5,
),
3 =>
array (
'number' => 2,
'letter' => 'a',
'price' => 9.99,
),
4 =>
array (
'number' => 3,
'letter' => 'b',
'price' => 9.99,
),
)
This technique is super powerful if you have dynamic rules being passed to your process. In my case, I needed to collect filters from my DataTables UI and regenerate the data as a .csv. I merely needed to iterate through DataTable's order data and derive my set of rules - done.
I find this syntax much kinder on the eyes versus call_user_func_array()
.
Here is a more complex implementation: Sort array of associative arrays on multiple columns using specified sorting rules
eval
it would be, but really, don't do it. I don't see why you can't do this with a loop and withoutarray_multisort
. – Yonina