PHP Array Sorting
last modified October 22, 2026
PHP provides a family of functions for sorting arrays and objects, such as
sort, asort, ksort, and
usort. This tutorial covers them with practical examples.
All PHP sorting functions sort the array in place: they take the array by
reference and return true, not a sorted copy. Since PHP 8.0,
sorting is stable, which means that elements that compare as equal keep their
original order.
| Function | Sorts by | Keeps keys | Order |
|---|---|---|---|
sort / rsort | value | no | ascending / descending |
asort / arsort | value | yes | ascending / descending |
ksort / krsort | key | yes | ascending / descending |
usort | value | no | user-defined |
uasort | value | yes | user-defined |
uksort | key | yes | user-defined |
natsort / natcasesort | value | yes | natural order |
Basic sorting with sort
The sort function sorts an array in ascending order and
reindexes it.
<?php declare(strict_types=1); $numbers = [3, 1, 4, 1, 5]; sort($numbers); print_r($numbers);
The array [3, 1, 4, 1, 5] becomes [1, 1, 3, 4, 5].
The keys are reset to 0 through 4.
$ php basic_sort.php
Array
(
[0] => 1
[1] => 1
[2] => 3
[3] => 4
[4] => 5
)
Sorting strings
Strings are sorted by their byte values, so uppercase letters come before lowercase ones.
<?php
declare(strict_types=1);
$fruits = ["banana", "apple", "Cherry", "date"];
sort($fruits);
echo implode(' ', $fruits), "\n";
sort($fruits, SORT_FLAG_CASE | SORT_STRING);
echo implode(' ', $fruits), "\n";
By default, "Cherry" comes first because C has a
lower code than any lowercase letter. The SORT_FLAG_CASE flag,
combined with SORT_STRING, makes the comparison
case-insensitive.
$ php sort_strings.php Cherry apple banana date apple banana Cherry date
Natural order
Natural ordering sorts numbers inside strings the way people expect.
<?php
declare(strict_types=1);
$files = ["img12.png", "img10.png", "img2.png", "img1.png"];
$copy = $files;
sort($copy);
echo implode(' ', $copy), "\n";
$copy = $files;
sort($copy, SORT_NATURAL);
echo implode(' ', $copy), "\n";
$files[] = "IMG3.png";
sort($files, SORT_NATURAL);
echo implode(' ', $files), "\n";
sort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo implode(' ', $files), "\n";
A plain sort puts img10.png before img2.png, because
it compares character by character. The SORT_NATURAL flag compares
the numeric parts as numbers. Adding SORT_FLAG_CASE also ignores
case. The natsort and natcasesort functions do the
same but keep the keys.
$ php natural.php img1.png img10.png img12.png img2.png img1.png img2.png img10.png img12.png IMG3.png img1.png img2.png img10.png img12.png img1.png img2.png IMG3.png img10.png img12.png
Preserving keys with asort and arsort
The asort function sorts by value while keeping the key
associations; arsort does the same in descending order.
<?php declare(strict_types=1); $scores = ["John" => 85, "Jane" => 92, "Bob" => 78]; asort($scores); print_r($scores); arsort($scores); print_r($scores);
The names stay attached to their scores. With sort, the names
would be lost and replaced by numeric keys.
$ php asort_example.php
Array
(
[Bob] => 78
[John] => 85
[Jane] => 92
)
Array
(
[Jane] => 92
[John] => 85
[Bob] => 78
)
Sorting by keys with ksort and krsort
The ksort function sorts an array by key in ascending order,
krsort in descending order.
<?php declare(strict_types=1); $data = ["z" => 1, "x" => 2, "y" => 3]; ksort($data); print_r($data); krsort($data); print_r($data);
The values stay tied to their original keys.
$ php ksort_example.php
Array
(
[x] => 2
[y] => 3
[z] => 1
)
Array
(
[z] => 1
[y] => 3
[x] => 2
)
Descending order with rsort
The rsort function sorts an array in descending order.
<?php
declare(strict_types=1);
$numbers = [3, 1, 4, 1, 5];
rsort($numbers);
echo implode(' ', $numbers), "\n";
The array is sorted from the largest to the smallest value and reindexed.
$ php rsort_example.php 5 4 3 1 1
Custom sorting with usort
The usort function sorts using a comparison callback.
<?php
declare(strict_types=1);
$numbers = [10, 5, 8, 3];
usort($numbers, fn(int $a, int $b): int => $b <=> $a);
echo implode(' ', $numbers), "\n";
$words = ["sky", "blue", "a", "cloud", "be"];
usort($words, fn(string $a, string $b): int => strlen($a) <=> strlen($b));
echo implode(' ', $words), "\n";
The callback receives two elements and returns a negative number, zero, or a
positive number if the first element should come before, at the same position
as, or after the second. The spaceship operator <=> returns
exactly these values. Swapping the operands, $b <=> $a,
reverses the order. The second call sorts words by length.
$ php usort_example.php 10 8 5 3 a be sky blue cloud
Sorting objects by property
Use usort to sort objects by a property value.
<?php
declare(strict_types=1);
final class Product
{
public function __construct(
public string $name,
public float $price,
) {}
}
$products = [
new Product("Phone", 500),
new Product("Laptop", 1000),
new Product("Tablet", 300),
];
usort($products, fn(Product $a, Product $b): int => $a->price <=> $b->price);
foreach ($products as $product) {
printf("%-8s %7.2f\n", $product->name, $product->price);
}
The products are ordered by price, from the cheapest to the most expensive.
$ php sort_objects.php Tablet 300.00 Phone 500.00 Laptop 1000.00
Sorting associative arrays with uasort
The uasort function sorts by value with a callback and preserves
the keys.
<?php declare(strict_types=1); $scores = ["John" => 85, "Jane" => 92, "Bob" => 78]; uasort($scores, fn(int $a, int $b): int => $b <=> $a); print_r($scores);
The scores are sorted in descending order, with the names intact.
$ php uasort_example.php
Array
(
[Jane] => 92
[John] => 85
[Bob] => 78
)
Sorting by key with uksort
The uksort function sorts by key using a callback.
<?php declare(strict_types=1); $data = ["kiwi" => 1, "fig" => 2, "banana" => 3, "plum" => 4]; uksort($data, fn(string $a, string $b): int => strlen($a) <=> strlen($b)); print_r($data);
The keys are sorted by length. The keys "kiwi" and
"plum" have the same length, so they keep their original order;
this is the stable sorting guaranteed since PHP 8.0.
$ php uksort_example.php
Array
(
[fig] => 2
[kiwi] => 1
[plum] => 4
[banana] => 3
)
Stable sorting
Stability matters when sorting data that is already ordered by another criterion.
<?php
declare(strict_types=1);
$tasks = [
["Write report", 2],
["Call client", 1],
["Fix bug", 1],
["Review code", 2],
["Reply to email", 1],
];
usort($tasks, fn(array $a, array $b): int => $a[1] <=> $b[1]);
foreach ($tasks as [$task, $priority]) {
echo "$priority $task\n";
}
The tasks are sorted by priority. Tasks with the same priority stay in the order in which they were added. Before PHP 8.0, their order was not guaranteed.
$ php stable.php 1 Call client 1 Fix bug 1 Reply to email 2 Write report 2 Review code
Sorting multidimensional arrays
Arrays of rows can be sorted by a specific key with usort.
<?php
declare(strict_types=1);
$users = [
["name" => "John", "age" => 25],
["name" => "Jane", "age" => 30],
["name" => "Bob", "age" => 20],
];
usort($users, fn(array $a, array $b): int => $a["age"] <=> $b["age"]);
foreach ($users as $user) {
echo "{$user['name']} ({$user['age']})\n";
}
The users are sorted by age, from the youngest to the oldest.
$ php sort_multi.php Bob (20) John (25) Jane (30)
Sorting by multiple criteria
Arrays are compared element by element with the spaceship operator, which makes multi-criteria sorting concise.
<?php
declare(strict_types=1);
final class Item
{
public function __construct(
public string $name,
public int $stock,
) {}
}
$items = [
new Item("Tablet", 5),
new Item("Phone", 10),
new Item("Laptop", 5),
new Item("Charger", 10),
];
usort($items, fn(Item $a, Item $b): int =>
[$b->stock, $a->name] <=> [$a->stock, $b->name]);
foreach ($items as $item) {
echo "$item->name ($item->stock)\n";
}
The items are sorted by stock in descending order and then by name in ascending
order. Putting $b->stock on the left side reverses the first
criterion. If the stock values are equal, the names decide.
$ php sort_multi_criteria.php Charger (10) Phone (10) Laptop (5) Tablet (5)
Sorting with array_multisort
The array_multisort function sorts several arrays at once. Combined
with array_column, it sorts rows by several columns.
<?php
declare(strict_types=1);
$users = [
["name" => "John", "age" => 25],
["name" => "Jane", "age" => 30],
["name" => "Bob", "age" => 25],
["name" => "Anna", "age" => 30],
];
$ages = array_column($users, 'age');
$names = array_column($users, 'name');
array_multisort($ages, SORT_DESC, $names, SORT_ASC, $users);
foreach ($users as $user) {
echo "{$user['name']} ({$user['age']})\n";
}
The ages are sorted in descending order, ties are broken by name in ascending
order, and the $users array, passed last, is rearranged in the
same way.
$ php array_multisort_example.php Anna (30) Jane (30) Bob (25) John (25)
Sorting users by age
This example sorts user objects by date of birth.
<?php
declare(strict_types=1);
final class User
{
public DateTimeImmutable $dateOfBirth;
public function __construct(
public string $firstName,
public string $lastName,
string $dateOfBirth,
) {
$this->dateOfBirth = new DateTimeImmutable($dateOfBirth);
}
}
$users = [
new User("John", "Doe", "2000-05-15"),
new User("Jane", "Smith", "1995-08-22"),
new User("Bob", "Brown", "1998-11-30"),
];
usort($users, fn(User $a, User $b): int => $a->dateOfBirth <=> $b->dateOfBirth);
$today = new DateTimeImmutable('2026-10-22');
foreach ($users as $user) {
$age = $user->dateOfBirth->diff($today)->y;
echo "$user->firstName $user->lastName, {$user->dateOfBirth->format('Y-m-d')}, $age years\n";
}
The date of birth is stored as a DateTimeImmutable, which can be
compared directly with the spaceship operator. The oldest user comes first. The
age is computed with diff against a fixed date to keep the output
stable.
$ php sort_users_by_age.php Jane Smith, 1995-08-22, 31 years Bob Brown, 1998-11-30, 27 years John Doe, 2000-05-15, 26 years
Getting a sorted copy
Because the sorting functions work in place, a small helper is useful when the original order must be kept.
<?php
declare(strict_types=1);
function sorted(array $values, ?callable $cmp = null): array
{
$cmp === null ? sort($values) : usort($values, $cmp);
return $values;
}
$numbers = [3, 1, 2];
$asc = sorted($numbers);
$desc = sorted($numbers, fn(int $a, int $b): int => $b <=> $a);
echo implode(' ', $numbers), "\n";
echo implode(' ', $asc), "\n";
echo implode(' ', $desc), "\n";
Arrays are passed to functions by value, so the helper sorts its own copy and
returns it. The original $numbers array is unchanged.
$ php sorted_copy.php 3 1 2 1 2 3 3 2 1
Best practices for sorting
- Pick the right function: use the
aandkvariants when keys carry meaning. - Use the spaceship operator: return
$a <=> $brather than$a - $b, which breaks for floats and large integers. - Compare arrays for multiple criteria:
[$a->x, $a->y] <=> [$b->x, $b->y]is easier to read than nested conditions. - Keep callbacks cheap: the comparison runs many times; precompute expensive values, such as parsed dates, before sorting.
Source
PHP Sorting Arrays - Documentation
In this article, we have explored sorting arrays and objects in PHP, including custom comparisons, natural order, stable sorting, and multi-criteria sorting.
Author
List all PHP tutorials.