Sorting Arrays
PHP has a family of sorting functions that differ in three ways: whether they sort by value or by key, whether they keep the key–value association, and in which direction. Add usort with the spaceship operator, and you can sort anything in any order.
Sorting lists
sort sorts values in ascending order; rsort in descending order. Both sort the array in place — they change the variable you pass and return true — and they renumber the keys:
<?php $numbers = [42, 7, 19, 3, 25]; sort($numbers); echo implode(", ", $numbers), "\n"; rsort($numbers); echo implode(", ", $numbers), "\n"; $words = ["pear", "Fig", "banana", "apple"]; sort($words); echo implode(", ", $words), "\n"; sort($words, SORT_FLAG_CASE | SORT_STRING); echo implode(", ", $words), "\n";
3, 7, 19, 25, 42 42, 25, 19, 7, 3 Fig, apple, banana, pear apple, banana, Fig, pear
By default, upper-case letters sort before lower-case ones (they come first in ASCII). The SORT_FLAG_CASE | SORT_STRING flags sort case-insensitively.
A common mistake is to write $sorted = sort($numbers); — $sorted would be true. Sort first, then use the variable.
Keeping keys: asort and arsort
For associative arrays, sort would throw away the keys. asort and arsort sort by value and keep each key with its value:
<?php $scores = ["Zoe" => 81, "Adam" => 92, "Mia" => 77, "Bob" => 92]; arsort($scores); print_r($scores); asort($scores); echo implode(", ", array_keys($scores)), "\n";
Array
(
[Adam] => 92
[Bob] => 92
[Zoe] => 81
[Mia] => 77
)
Mia, Zoe, Adam, BobPHP's sorting is stable (since PHP 8.0): elements that compare equal keep their original order — Adam stays before Bob.
Sorting by key: ksort and krsort
<?php $capitals = ["Peru" => "Lima", "Chad" => "N'Djamena", "Fiji" => "Suva"]; ksort($capitals); print_r($capitals); krsort($capitals); echo implode(", ", array_keys($capitals)), "\n";
Array
(
[Chad] => N'Djamena
[Fiji] => Suva
[Peru] => Lima
)
Peru, Fiji, ChadNatural order
Normal string sorting puts "img12" before "img2", because it compares character by character. natsort (and natcasesort) sort the way people expect:
<?php $files = ["img12.png", "img10.png", "img2.png", "img1.png"]; $copy = $files; sort($copy); echo implode(" ", $copy), "\n"; natsort($files); echo implode(" ", $files), "\n";
img1.png img10.png img12.png img2.png img1.png img2.png img10.png img12.png
Custom sorting with usort
usort sorts with your own comparison function, which receives two elements and returns a negative number, zero or a positive number. The spaceship operator <=> produces exactly that:
<?php $products = [ ["name" => "Laptop", "category" => "Electronics", "price" => 999], ["name" => "Desk", "category" => "Furniture", "price" => 249], ["name" => "Mouse", "category" => "Electronics", "price" => 25], ["name" => "Chair", "category" => "Furniture", "price" => 129], ]; usort($products, fn($a, $b) => $a["price"] <=> $b["price"]); echo implode(", ", array_column($products, "name")), "\n"; usort($products, fn($a, $b) => $b["price"] <=> $a["price"]); // swap for descending echo implode(", ", array_column($products, "name")), "\n"; // by category, then by price within each category usort($products, fn($a, $b) => [$a["category"], $a["price"]] <=> [$b["category"], $b["price"]]); foreach ($products as $p) { echo "{$p['category']}: {$p['name']} ({$p['price']})\n"; }
Mouse, Chair, Desk, Laptop Laptop, Desk, Chair, Mouse Electronics: Mouse (25) Electronics: Laptop (999) Furniture: Chair (129) Furniture: Desk (249)
Comparing two arrays with <=> compares them element by element, which makes multi-level sorting a one-liner. uasort does the same while keeping keys, and uksort sorts by key with a custom function.
Sorting without changing the original
Since the sort functions work in place, copy the array first if you need the original order too. A small helper makes this read nicely:
<?php function sorted(array $items, ?callable $compare = null): array { $compare ? usort($items, $compare) : sort($items); return $items; // $items is a copy, so the caller's array is unchanged } $original = [3, 1, 2]; echo implode(",", sorted($original)), "\n"; echo implode(",", sorted($original, fn($a, $b) => $b <=> $a)), "\n"; echo implode(",", $original), "\n";
1,2,3 3,2,1 3,1,2
Shuffling and reversing
<?php $deck = range(1, 10); shuffle($deck); // random order, in place echo count($deck), " cards, all present: ", array_sum($deck) === 55 ? "yes" : "no", "\n"; echo implode(" ", array_reverse(["a", "b", "c"])), "\n";
10 cards, all present: yes c b a
Which function?
| Sort by | Keys | Ascending | Descending | Custom |
|---|---|---|---|---|
| Value | Renumbered | sort | rsort | usort |
| Value | Kept | asort | arsort | uasort |
| Key | Kept | ksort | krsort | uksort |
Try it yourself
Sort a league table by points (highest first), then by goal difference, then alphabetically by team name.
1. City 15 pts GD +8 2. United 12 pts GD +9 3. Athletic 12 pts GD +5 4. Rovers 12 pts GD +5