natsort
Sorts an array by value using a natural order algorithm, keeping key/value associations.
natsort(array &$array): true- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$array | array | The array to sort. Passed by reference and modified directly; keys are preserved. |
Return value
trueAlways returns true. The array is sorted in place through the reference.
Errors
Nothing. A non-array argument raises a TypeError from the parameter type.
Changelog
- PHP 8.2The return type is true now; previously it was bool.
- PHP 8.0Elements that compare as equal keep their original order; before 8.0 their relative order was undefined.
And natural order is not version-number order: each digit run is compared as a number, so 1.9 sorts before 1.10 — which happens to match version semantics here, but pre-release suffixes break it, and natsort puts 1.0 before 1.0-beta while version_compare correctly puts the beta first. (strnatcmp('1.10', '1.9') returns 1, i.e. 1.10 is greater; this also contradicted the page's own second example, which correctly prints 1.2 1.9 1.10.)
Example
When to use it
- Display uploaded screenshots named shot1.png … shot12.png in capture order rather than byte order.
- Order rotated log files app.1.log, app.2.log, app.10.log before concatenating them.
- Sort human-entered reference codes such as ITEM-2, ITEM-10 in a picking list.
Frequently asked questions
Why does natsort put img10 after img2?
That is the intended behaviour: natsort compares the digit runs as numbers, so 2 < 10. A plain sort compares them as text, where the character '1' is less than '2', which is what puts img10 first.
Is natsort case sensitive?
Yes. Uppercase letters sort before lowercase ones, so 'Img3' precedes 'img1'. Use natcasesort for case-insensitive natural ordering.
How do I natural-sort an array of arrays by one field?
Use usort with strnatcmp on the field you care about, for example usort($rows, fn($a, $b) => strnatcmp($a['file'], $b['file'])).
More examples
Keys survive the sort
The loop prints c, b, a in that order — the values are now in natural order and each string is still paired with its original key. array_values discards the keys to give a plain JSON array.
<?php
$logs = ['a' => 'app.10.log', 'b' => 'app.2.log', 'c' => 'app.1.log'];
natsort($logs);
foreach ($logs as $key => $file) {
echo "$key => $file\n";
}
echo json_encode(array_values($logs)), "\n";Natural order is not version order
natsort prints 1.2 1.9 1.10 by treating the text after the dot as a number, which happens to look right here but breaks for 1.9.1 style strings. version_compare applies real version semantics and is the correct tool for release numbers.
<?php
$v = ['1.9', '1.10', '1.2'];
$nat = $v; natsort($nat);
echo 'natsort: ', implode(' ', $nat), "\n";
$ver = $v; usort($ver, 'version_compare');
echo 'version: ', implode(' ', $ver), "\n";
Discussion