Sorting Arrays
Sorting arranges array elements in a defined order — numbers from lowest to highest, names alphabetically, products by price, orders by date. PHP provides a family of sorting functions that differ in
Sorting arranges array elements in a defined order — numbers from lowest to highest, names alphabetically, products by price, orders by date. PHP provides a family of sorting functions that differ in what they sort by (values or keys), whether they keep keys, and how they compare elements.
Overview of Sorting Functions
| Function | Sorts By | Order | Keeps Key–Value Association? |
|---|---|---|---|
sort() | Value | Ascending | No — re-indexes from 0 |
rsort() | Value | Descending | No |
asort() | Value | Ascending | Yes |
arsort() | Value | Descending | Yes |
ksort() | Key | Ascending | Yes |
krsort() | Key | Descending | Yes |
usort() | Value, custom comparison | Custom | No |
uasort() | Value, custom comparison | Custom | Yes |
uksort() | Key, custom comparison | Custom | Yes |
natsort() / natcasesort() | Value, "natural" order | Ascending | Yes |
array_multisort() | One or more arrays/columns | Configurable | Re-indexes integer keys |
Rules That Apply to All of Them
- They sort the array in place (they take it by reference) and return
true. They do not return the sorted array. - Since PHP 8.0, sorting is stable: elements that compare as equal keep their original relative order.
sort() and rsort() — Lists
<?php
$scores = [72, 95, 64, 88];
sort($scores);
echo implode(', ', $scores) . "\n";
rsort($scores);
echo implode(', ', $scores) . "\n";
Output
64, 72, 88, 95
95, 88, 72, 64
sort() and rsort() re-index the result from 0. Use them for lists, where keys are just positions.
Using sort() on an Associative Array Loses the Keys
<?php
$prices = ['Mouse' => 799, 'Keyboard' => 1499, 'Cable' => 199];
sort($prices);
print_r($prices);
Output
Array
(
[0] => 199
[1] => 799
[2] => 1499
)
The product names are gone. For associative arrays, use asort() / arsort() instead.
asort(), arsort(), ksort(), krsort() — Keeping Keys
<?php
$prices = ['Mouse' => 799, 'Keyboard' => 1499, 'Cable' => 199];
arsort($prices);
echo "By price (high to low): " . implode(', ', array_keys($prices)) . "\n";
krsort($prices);
echo "By name (Z to A): " . implode(', ', array_keys($prices)) . "\n";
ksort($prices);
echo "By name (A to Z): " . implode(', ', array_keys($prices)) . "\n";
Output
By price (high to low): Keyboard, Mouse, Cable
By name (Z to A): Mouse, Keyboard, Cable
By name (A to Z): Cable, Keyboard, Mouse
The a prefix stands for associative (sort by value, keep keys), and k for key.
How Values Are Compared: Sort Flags
By default, PHP compares elements using its standard comparison rules. The optional second argument changes this.
| Flag | Comparison |
|---|---|
SORT_REGULAR (default) | Standard PHP comparison (numeric strings compared as numbers) |
SORT_NUMERIC | Compare as numbers |
SORT_STRING | Compare as strings, byte by byte |
SORT_NATURAL | "Natural" order: numbers inside strings compared as numbers |
SORT_FLAG_CASE | Combine with SORT_STRING or SORT_NATURAL to ignore case |
Case Sensitivity
<?php
$names = ['banana', 'apple', 'Cherry'];
sort($names);
echo implode(', ', $names) . "\n";
sort($names, SORT_STRING | SORT_FLAG_CASE);
echo implode(', ', $names) . "\n";
Output
Cherry, apple, banana
apple, banana, Cherry
By default, uppercase letters sort before all lowercase letters (because their byte values are smaller). SORT_STRING | SORT_FLAG_CASE sorts case-insensitively.
Numeric Strings
<?php
$values = ['10', '9', '2', '1'];
sort($values);
echo implode(', ', $values) . "\n";
sort($values, SORT_STRING);
echo implode(', ', $values) . "\n";
Output
1, 2, 9, 10
1, 10, 2, 9
The default comparison treats numeric strings as numbers. SORT_STRING compares character by character, which puts "10" before "2" — correct for codes, wrong for quantities. Store numbers as integers to avoid ambiguity.
Natural Order
<?php
$files = ['img12.png', 'img10.png', 'IMG2.png', 'img1.png'];
sort($files, SORT_NATURAL | SORT_FLAG_CASE);
echo implode(', ', $files) . "\n";
Output
img1.png, IMG2.png, img10.png, img12.png
Natural sorting orders embedded numbers by value (2 before 10) — the order people expect for file names, versions, and labels. natcasesort($files) does the same while keeping keys.
Custom Sorting: usort(), uasort(), uksort()
When elements are records or need special rules, pass a comparison function. It receives two elements and returns a negative number, zero, or a positive number — exactly what the spaceship operator <=> produces (see Spaceship Operator).
usort() — Sorting Records by Several Fields
<?php
$products = [
['name' => 'Desk Lamp', 'category' => 'Home', 'price' => 1299],
['name' => 'Gel Pen', 'category' => 'Stationery', 'price' => 20],
['name' => 'Cushion', 'category' => 'Home', 'price' => 499],
['name' => 'Notebook', 'category' => 'Stationery', 'price' => 60],
];
usort($products, fn(array $a, array $b): int =>
[$a['category'], $b['price']] <=> [$b['category'], $a['price']]
);
foreach ($products as $p) {
echo "{$p['category']} - {$p['name']}: ₹{$p['price']}\n";
}
Output
Home - Desk Lamp: ₹1299
Home - Cushion: ₹499
Stationery - Notebook: ₹60
Stationery - Gel Pen: ₹20
Comparing arrays element by element sorts by category (ascending, because $a is on the left) and then by price (descending, because $b is on the left).
uasort() — Custom Sort, Keeping Keys
<?php
$catalog = [
'LAMP-01' => ['name' => 'Desk Lamp', 'price' => 1299],
'PEN-01' => ['name' => 'Gel Pen', 'price' => 20],
'NB-A5' => ['name' => 'Notebook', 'price' => 60],
];
uasort($catalog, fn(array $a, array $b): int => $a['price'] <=> $b['price']);
echo implode(', ', array_keys($catalog)) . "\n";
Output
PEN-01, NB-A5, LAMP-01
The SKUs remain the keys, so each product can still be found by its code after sorting.
uksort() — Custom Order of Keys
<?php
$stockBySize = ['L' => 4, 'S' => 10, 'XL' => 2, 'M' => 7];
$sizeOrder = array_flip(['S', 'M', 'L', 'XL']); // ['S' => 0, 'M' => 1, ...]
uksort($stockBySize, fn(string $a, string $b): int => $sizeOrder[$a] <=> $sizeOrder[$b]);
foreach ($stockBySize as $size => $quantity) {
echo "$size: $quantity\n";
}
Output
S: 10
M: 7
L: 4
XL: 2
Alphabetical order would put L before M and S. A lookup array that maps each size to its rank defines a custom order, a common technique for sizes, priorities, or workflow statuses.
array_multisort() — Sorting by Columns
array_multisort() sorts one or more arrays together. A common use is sorting records by columns extracted with array_column():
<?php
$students = [
['name' => 'Kavin', 'score' => 82],
['name' => 'Anu', 'score' => 95],
['name' => 'Bala', 'score' => 82],
];
array_multisort(
array_column($students, 'score'), SORT_DESC,
array_column($students, 'name'), SORT_ASC,
$students
);
foreach ($students as $student) {
echo "{$student['name']}: {$student['score']}\n";
}
Output
Anu: 95
Bala: 82
Kavin: 82
The score column is sorted descending; ties are broken by name ascending; and $students (the last argument) is rearranged in the same order. For most cases, usort() with the spaceship operator is easier to read; array_multisort() is useful when you already have column arrays.
Sorting Without Changing the Original
Sorting functions modify their argument. To keep the original order as well, sort a copy — passing an array to a function copies it automatically:
<?php
function sorted(array $values): array
{
sort($values);
return $values;
}
$arrivalOrder = ['Charu', 'Asha', 'Bala'];
$alphabetical = sorted($arrivalOrder);
echo implode(', ', $arrivalOrder) . "\n";
echo implode(', ', $alphabetical) . "\n";
Output
Charu, Asha, Bala
Asha, Bala, Charu
Related Functions
| Function | Purpose |
|---|---|
array_reverse($array, $preserveKeys) | Reverse the current order |
shuffle($array) | Random order (not cryptographically secure; see PHP Random Numbers) |
Collator::sort() (intl extension) | Locale-aware sorting of names with accents or non-English letters |
Common Mistakes
Assigning the Result of a Sort Function
<?php
$numbers = [3, 1, 2];
$sorted = sort($numbers);
var_dump($sorted);
Output
bool(true)
Sort functions return true and modify the array in place. Use $numbers after calling sort($numbers), or use a helper like sorted().
Using sort() on Associative Arrays
Effect: Keys are replaced with 0, 1, 2, ….
Fix: Use asort(), arsort(), ksort(), krsort(), or uasort().
Unexpected Case or Number Ordering
Effect: Uppercase words come first; "10" sorts before "2" with string comparison.
Fix: Use SORT_FLAG_CASE, SORT_NATURAL, or store numbers as numbers.
Returning Booleans From Comparison Functions
Effect: A deprecation notice and unreliable ordering.
Fix: Return $a <=> $b.
Sorting Large Data in PHP Instead of the Database
Effect: Loading thousands of rows just to sort them wastes memory and time.
Fix: Use SQL ORDER BY and fetch only the rows you need.
Best Practices
- Use
sort()/rsort()for lists and thea/kvariants for associative arrays. - Use
usort()/uasort()with the spaceship operator for records and multi-field sorts. - Choose flags deliberately for case-insensitive or natural ordering.
- Remember that sorting is in place; sort a copy when the original order matters.
- Sort in the database when data comes from a query.
Official reference: https://www.php.net/manual/en/array.sorting.php