PHPSorting Arrays

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
<?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
<?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
<?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
<?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.

usort() always reindexes, even on associative input
Passing an associative array to `usort()` will still strip its string keys and replace them with sequential integers, just like `sort()` does. If you need to keep the original keys while using a custom comparator, use `uasort()` instead - a very easy detail to miss.

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() and natcasesort() 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 $a and $b in the callback rather than writing a second function.

PHP 8 sorts are stable
As of PHP 8.0, all of PHP's sort functions are **stable**: elements that compare as equal keep their original relative order. Before PHP 8, equal elements could be reordered unpredictably, so code that depended on stability needed a workaround (like adding the original index as a tiebreaker). That workaround is no longer necessary on PHP 8.x.
Tip
When in doubt about which sort function to use, ask two questions in order: "do I need to sort by key or by value?" and "do I need to keep the original keys?" The answers point directly at one of the nine functions in the table above.