Signature
natsort(array &$array): truePurpose
natsort() sorts an array by its values using a "natural order" algorithm. Natural order compares runs of digits as numbers instead of character by character, so img2.png comes before img10.png. A plain string sort puts img10.png first because the character 1 is smaller than 2.
The function keeps key/value associations. Each value moves to its new position but keeps its original key. That is useful for file names, version labels and product codes such as item12.
Signature
Parameters and defaults
natsort() takes one parameter and has no optional parameters.
$array: the array to sort. It is passed by reference, so the function changes your variable in place. You cannot pass a literal array or the result of a function call directly.
The comparison is case-sensitive. There is no flag argument. If you need case-insensitive behavior, use natcasesort().
Return value and failure cases
The function always returns true. Since PHP 8.2 the declared return type is true; earlier versions declared bool. The return value carries no information, so the sorted result is in the array you passed in. Do not write $sorted = natsort($items); and expect an array.
Passing something that is not an array raises a TypeError. An empty array or a one-element array is valid and stays unchanged.
Two side effects are worth knowing. The function resets the array's internal pointer to the first element. If two members compare as equal, they keep their original relative order. Before PHP 8.0.0 that order was undefined.
Example 1: basic natural sorting
The first example sorts image names and prints the return value. The keys are preserved, so JSON encodes the result as an object keyed by the old positions.
$files = ["img12.png", "img10.png", "img2.png", "img1.png"];
$result = natsort($files);
echo var_export($result, true), "\n";
echo json_encode($files, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";true
{"3":"img1.png","2":"img2.png","1":"img10.png","0":"img12.png"}
The return value is true. The array is ordered 1, 2, 10, 12, but each name still has the key it started with.
Example 2: compare with a string sort and reindex
Version-like labels show the difference from a standard sort. After natsort(), call array_values() when you want a clean list with keys 0, 1, 2, ....
$versions = ["v1.10", "v1.2", "v1.9", "v1.1"];
$standard = $versions;
sort($standard, SORT_STRING);
natsort($versions);
echo json_encode($standard, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_values($versions), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";["v1.1","v1.10","v1.2","v1.9"] ["v1.1","v1.2","v1.9","v1.10"]
The string sort places v1.10 right after v1.1. Natural order treats the final 10 as ten and places it last. Reindexing gives a JSON list instead of an object.
Example 3: case sensitivity
natsort() compares letters case-sensitively, so uppercase ASCII letters sort before lowercase ones. natcasesort() ignores the case difference.
$names = ["item10", "Item2", "item1", "Item11"];
$caseSensitive = $names;
$caseInsensitive = $names;
natsort($caseSensitive);
natcasesort($caseInsensitive);
echo json_encode(array_values($caseSensitive), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_values($caseInsensitive), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";["Item2","Item11","item1","item10"] ["item1","Item2","item10","Item11"]
The first line keeps both capitalized names ahead of the lowercase ones. The second line mixes them in true natural order by number.
Edge cases
- Negative numbers. The minus sign is just another character. In the manual's example, the strings
-5,-2and-1000do not end up in numeric order. Usesort()with numeric flags for real numbers. - Leading zeros. Values such as
09,009and011are compared with special handling for zero padding, so the result may not match what you expect from numeric value alone. Test with your real data. - Equal members. Items that compare as equal keep their original order.
- Sorting by keys.
natsort()only looks at values. To order by keys naturally, useuksort()withstrnatcmp(). - Internal pointer. The array's pointer is reset to the first element after sorting.
Common mistakes
- Using the return value as the sorted array. It is always
true. Read the original variable. - Expecting a reindexed list. Keys are preserved. Wrap the array in
array_values()if you need sequential keys, especially before JSON encoding or indexed access. - Forgetting case sensitivity. Mixed-case names can sort in a surprising order. Choose
natcasesort()when case should not matter. - Treating it as a numeric sort. It is meant for alphanumeric strings. Signs and padding follow the algorithm's rules, not arithmetic.
- Passing a temporary value. The parameter is by reference, so assign the array to a variable first.
Related functions
natcasesort(): the case-insensitive natural-order sort.strnatcmp(): compares two strings in natural order and is handy in callbacks.strnatcasecmp(): the case-insensitive comparison counterpart.sort()andasort(): standard comparison sorts.asort()also preserves keys.
Recap
Use natsort() to sort values so embedded numbers read the way a person expects, while keeping each original key. It changes the array in place, always returns true, is case-sensitive and does not treat signs as numbers. Reindex with array_values() when you need a list, and switch to natcasesort() when letter case should be ignored.
Tested examples
$files = ["img12.png", "img10.png", "img2.png", "img1.png"];
$result = natsort($files);
echo var_export($result, true), "\n";
echo json_encode($files, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
true
{"3":"img1.png","2":"img2.png","1":"img10.png","0":"img12.png"}
$versions = ["v1.10", "v1.2", "v1.9", "v1.1"];
$standard = $versions;
sort($standard, SORT_STRING);
natsort($versions);
echo json_encode($standard, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_values($versions), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
["v1.1","v1.10","v1.2","v1.9"] ["v1.1","v1.2","v1.9","v1.10"]
$names = ["item10", "Item2", "item1", "Item11"];
$caseSensitive = $names;
$caseInsensitive = $names;
natsort($caseSensitive);
natcasesort($caseInsensitive);
echo json_encode(array_values($caseSensitive), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
echo json_encode(array_values($caseInsensitive), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), "\n";
["Item2","Item11","item1","item10"] ["item1","Item2","item10","Item11"]