Sorting Arrays
PHP has a whole family of sorting functions rather than one universal sort(), and the differences between them come down to two questions: does the function keep the original keys, and does it sort by value or by key? Picking the wrong one is a common source of "my associative array turned into an indexed array" bugs, so it is worth learning them as a group rather than one at a time.
sort() and rsort(): reindex, lose keys
sort() orders values ascending; rsort() orders them descending. Both discard the original keys and reassign fresh sequential integer keys starting at 0. That makes them a good fit for plain indexed arrays, but a poor choice for associative arrays where the keys carry meaning.
sort() renumbers everything
<?php $scores = ["b" => 40, "a" => 95, "c" => 70]; sort($scores); // ascending, keys are discarded print_r($scores);
Array
(
[0] => 40
[1] => 70
[2] => 95
)asort() and arsort(): preserve keys
asort() sorts by value ascending while keeping each value attached
to its original key; arsort() does the same in descending order.
These are the correct choice whenever the keys matter - for example,
ranking a ["name" => score] map without losing which name goes with
which score.
Sorting a leaderboard, keeping names attached
<?php $scores = ["Ana" => 91, "Bo" => 78, "Cy" => 85]; arsort($scores); // highest score first, names preserved print_r($scores);
Array
(
[Ana] => 91
[Cy] => 85
[Bo] => 78
)ksort() and krsort(): sort by key
ksort() and krsort() ignore the values entirely and sort the array by its keys instead - ascending and descending respectively. This is useful for putting an associative array into alphabetical (or numeric) key order, such as displaying configuration options in a predictable sequence.
Alphabetizing by key
<?php $config = ["timeout" => 30, "cache" => true, "debug" => false]; ksort($config); print_r($config);
Array
(
[cache] => 1
[debug] =>
[timeout] => 30
)Custom comparisons: usort(), uasort(), uksort()
When the built-in ascending/descending order is not enough - sorting by string length, by a nested field, by a custom priority - you supply your own comparison function. usort() sorts by value and reindexes (like sort()); uasort() sorts by value and keeps keys (like asort()); uksort() sorts by key using your comparator (like ksort()). The comparator receives two elements and must return a negative number, zero, or a positive number, exactly like the classic C strcmp() convention.
Custom sort with the spaceship operator
<?php
$people = [
["name" => "Ravi", "age" => 34],
["name" => "Sam", "age" => 22],
["name" => "Yui", "age" => 41],
];
usort($people, function ($a, $b) {
return $a["age"] <=> $b["age"]; // spaceship: -1, 0, or 1
});
foreach ($people as $person) {
echo "{$person['name']} ({$person['age']})\n";
}Sam (22) Ravi (34) Yui (41)
The <=> spaceship operator (PHP 7+) is the standard building block
for comparators: $a <=> $b returns -1 if $a is less, 0 if
equal, 1 if greater - exactly what usort() and friends expect,
without you having to write out if/elseif chains by hand.
Function | Sorts by | Keeps original keys? | Direction/comparator |
|---|---|---|---|
sort() | value | No | ascending |
rsort() | value | No | descending |
asort() | value | Yes | ascending |
arsort() | value | Yes | descending |
ksort() | key | Yes | ascending |
krsort() | key | Yes | descending |
usort() | value | No | custom callback |
uasort() | value | Yes | custom callback |
uksort() | key | Yes | custom callback |
All of these functions sort the array in place and return
true/false, not a new sorted array - assign the result of a chained expression, not the return value, if you need to keep using it.natsort()andnatcasesort()sort strings the way a human would ("img2" before "img10"), unlike the default sort which compares character by character.You can flip almost any "ascending" comparator to descending by swapping
$aand$bin the callback rather than writing a second function.