Sort functions change the array
PHP's sort functions sort the array in place: they rearrange the variable you pass and return true. They do not return a sorted copy, which catches out almost everyone once:
<?php
$prices = [24.99, 9.5, 89.5, 18.75];
$result = sort($prices);
var_dump($result);
print_r($prices);bool(true)
Array
(
[0] => 9.5
[1] => 18.75
[2] => 24.99
[3] => 89.5
)If you need to keep the original order too, copy the array first: $sorted = $prices; sort($sorted);. Arrays are copied on assignment in PHP, so that is safe.
Lists: sort and rsort
sort() sorts values from lowest to highest, and rsort() from highest to lowest. Both throw away the old keys and renumber from 0, which is right for plain lists:
<?php
$names = ["Kavya", "asha", "Liam", "Farid"];
sort($names);
print_r($names);
rsort($names);
echo implode(", ", $names) . "\n";Array
(
[0] => Farid
[1] => Kavya
[2] => Liam
[3] => asha
)
asha, Liam, Kavya, FaridNotice asha comes last. Strings are compared byte by byte, and all uppercase letters come before lowercase ones. Flags fix that, as shown further down.
Associative arrays: asort, arsort, ksort, krsort
For associative arrays, renumbering would destroy the data: you would lose which price belongs to which product. asort() and arsort() sort by value and keep each key with its value; ksort() and krsort() sort by key:
<?php
$stock = ["Keyboard" => 60, "Headphones" => 25, "Mug" => 120, "Desk Mat" => 40];
asort($stock);
print_r($stock);
arsort($stock);
echo "Most stocked: " . array_key_first($stock) . "\n";
ksort($stock);
echo implode(", ", array_keys($stock)) . "\n";Array
(
[Headphones] => 25
[Desk Mat] => 40
[Keyboard] => 60
[Mug] => 120
)
Most stocked: Mug
Desk Mat, Headphones, Keyboard, Mugarray_key_first() and array_key_last() return the first and last keys, which after a sort gives you the top or bottom item.
A quick way to remember the names: a means associative (keep keys), k means sort by key, r means reverse.
Sort flags
Most sort functions take a second argument that changes how values are compared:
<?php
$files = ["img12.png", "img10.png", "IMG2.png", "img1.png"];
$plain = $files;
sort($plain);
echo implode(" ", $plain) . "\n";
$natural = $files;
sort($natural, SORT_NATURAL | SORT_FLAG_CASE);
echo implode(" ", $natural) . "\n";
$codes = ["10", "9", "100"];
sort($codes, SORT_STRING);
echo implode(" ", $codes) . "\n";IMG2.png img1.png img10.png img12.png
img1.png IMG2.png img10.png img12.png
10 100 9SORT_NATURAL compares the numbers inside strings as numbers, the way a person would ("img2" before "img10"), and SORT_FLAG_CASE ignores upper and lower case. SORT_STRING forces text comparison, and SORT_NUMERIC forces number comparison.
Rows: usort with a callback
Rows of data, such as products, need to be sorted by one of their fields. usort() takes a comparison callback that receives two elements and returns a negative number, zero or a positive number. The spaceship operator returns exactly that:
<?php
$products = [
["name" => "Yoga Mat", "category" => "Sports", "price" => 24.99],
["name" => "Mechanical Keyboard", "category" => "Electronics", "price" => 89.5],
["name" => "Water Bottle", "category" => "Sports", "price" => 12.0],
["name" => "Headphones", "category" => "Electronics", "price" => 199.99],
];
usort($products, fn($a, $b) => $b["price"] <=> $a["price"]);
foreach ($products as $p) {
echo "{$p['price']} {$p['name']}\n";
}199.99 Headphones
89.5 Mechanical Keyboard
24.99 Yoga Mat
12 Water BottleSwapping $a and $b reversed the order, giving most expensive first. usort() renumbers keys like sort(); uasort() keeps them, and uksort() compares keys.
Sorting by several fields
To sort by category, then by price within each category, compare arrays: <=> compares arrays element by element, so the second field only matters when the first is equal:
<?php
$products = [
["name" => "Yoga Mat", "category" => "Sports", "price" => 24.99],
["name" => "Mechanical Keyboard", "category" => "Electronics", "price" => 89.5],
["name" => "Water Bottle", "category" => "Sports", "price" => 12.0],
["name" => "Headphones", "category" => "Electronics", "price" => 199.99],
];
usort($products, fn($a, $b) => [$a["category"], $a["price"]] <=> [$b["category"], $b["price"]]);
foreach ($products as $p) {
printf("%-12s %7.2f %s\n", $p["category"], $p["price"], $p["name"]);
}Electronics 89.50 Mechanical Keyboard
Electronics 199.99 Headphones
Sports 12.00 Water Bottle
Sports 24.99 Yoga MatSince PHP 8.0 all sorts are stable: elements that compare as equal keep their original relative order. That means you can also sort twice, first by the secondary field and then by the main one.
When to sort in the database
If the data comes from MySQL, it is usually better to sort there with ORDER BY (see the MySQL lesson on ORDER BY): the database can use an index and only send the rows you need. Sort in PHP when the data is already in memory, or comes from somewhere else, such as an API.
Common mistakes
- Assigning the result of sort(), which is
true, not the array. - Using sort() on an associative array and losing the keys. Use
asort()orksort(). - Returning a boolean from a usort callback (
$a > $b). It must return a number; use<=>. - Forgetting case and natural order when sorting names or file names.
Exercise
Sort these customers by city (A to Z), then by last name within the same city, and print "City: First Last" for each: Asha Verma (Delhi), Farid Khan (Mumbai), Kavya Nair (Bengaluru), Rohan Mehta (Delhi), Liam O'Brien (Dublin).
Show one possible answer
<?php
$customers = [
["first" => "Asha", "last" => "Verma", "city" => "Delhi"],
["first" => "Farid", "last" => "Khan", "city" => "Mumbai"],
["first" => "Kavya", "last" => "Nair", "city" => "Bengaluru"],
["first" => "Rohan", "last" => "Mehta", "city" => "Delhi"],
["first" => "Liam", "last" => "O'Brien", "city" => "Dublin"],
];
usort($customers, fn($a, $b) => [$a["city"], $a["last"]] <=> [$b["city"], $b["last"]]);
foreach ($customers as $c) {
echo "{$c['city']}: {$c['first']} {$c['last']}\n";
}Bengaluru: Kavya Nair
Delhi: Rohan Mehta
Delhi: Asha Verma
Dublin: Liam O'Brien
Mumbai: Farid KhanKey points
- sort and rsort sort values and renumber the keys; asort and arsort keep each key with its value.
- ksort and krsort sort by key.
- usort, uasort and uksort take a comparison callback, usually written with the spaceship operator <=>.
- Sort functions change the array in place and return true, not the sorted array.