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
<?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";
Output
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
<?php

$scores = ["Zoe" => 81, "Adam" => 92, "Mia" => 77, "Bob" => 92];

arsort($scores);
print_r($scores);

asort($scores);
echo implode(", ", array_keys($scores)), "\n";
Output
Array
(
    [Adam] => 92
    [Bob] => 92
    [Zoe] => 81
    [Mia] => 77
)
Mia, Zoe, Adam, Bob

PHP'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
<?php

$capitals = ["Peru" => "Lima", "Chad" => "N'Djamena", "Fiji" => "Suva"];
ksort($capitals);
print_r($capitals);
krsort($capitals);
echo implode(", ", array_keys($capitals)), "\n";
Output
Array
(
    [Chad] => N'Djamena
    [Fiji] => Suva
    [Peru] => Lima
)
Peru, Fiji, Chad

Natural order

Normal string sorting puts "img12" before "img2", because it compares character by character. natsort (and natcasesort) sort the way people expect:

PHP
<?php

$files = ["img12.png", "img10.png", "img2.png", "img1.png"];

$copy = $files;
sort($copy);
echo implode(" ", $copy), "\n";

natsort($files);
echo implode(" ", $files), "\n";
Output
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
<?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";
}
Output
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
<?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";
Output
1,2,3
3,2,1
3,1,2

Shuffling and reversing

PHP
<?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";
Output
10 cards, all present: yes
c b a

Which function?

Sort byKeysAscendingDescendingCustom
ValueRenumberedsortrsortusort
ValueKeptasortarsortuasort
KeyKeptksortkrsortuksort

Try it yourself

Sort a league table by points (highest first), then by goal difference, then alphabetically by team name.

Try it yourself · main.php
Edit the code, copy it into main.php, then run it with php main.php (PHP 8.5). How to install PHP
Output
1. City      15 pts  GD +8
2. United    12 pts  GD +9
3. Athletic  12 pts  GD +5
4. Rovers    12 pts  GD +5