strnatcasecmp
Compares two strings in human "natural" order, ignoring letter case.
strnatcasecmp(string $string1, string $string2): int- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$string1 | string | The first string. |
$string2 | string | The second string. |
Return value
intA value less than 0 if string1 is less than string2, a value greater than 0 if string1 is greater than string2, and 0 if they are equal.
Changelog
- PHP 8.2.0This function is no longer guaranteed to return strlen($string1) - strlen($string2) when string lengths are not equal, but may now return -1 or 1 instead.
strnatcasecmp() is the case-insensitive twin of strnatcmp(). It compares two strings using a "natural order" algorithm: runs of digits are compared as numbers rather than character by character, so Item2 sorts before item10 instead of after it.
When to reach for it
Use it as the comparison callback whenever you are ordering names that mix words and numbers and the case is inconsistent — uploaded filenames, chapter titles, track listings, ticket references typed by different people. Pass it straight to usort():
usort($files, 'strnatcasecmp');For arrays where you need to keep the keys, natcasesort() does the same ordering in place.
What trips people up
The return value is only meaningful by its sign. Since PHP 8.2 it is typically -1, 0 or 1, but older code that relied on the difference of the string lengths will break. Always compare with < 0, === 0 or > 0.
Natural order is not version comparison. For semantic versions use version_compare(), which understands suffixes like -beta; strnatcasecmp() just sees letters.
Case folding is ASCII only, so accented letters are compared by byte value.
Example
When to use it
- Sort a list of uploaded filenames such as IMG2.png, img10.png, IMG12.png into the order a person expects.
- Order chapter or section titles like "Chapter 2" and "Chapter 10" where the author's capitalisation is inconsistent.
- Group and sort ticket references such as BUG-9 and bug-100 typed by different users.
Frequently asked questions
What is the difference between strnatcasecmp and strcasecmp?
strcasecmp compares character by character, so "item10" sorts before "item2". strnatcasecmp compares runs of digits as numbers, giving the order a human would use. Both ignore letter case.
How do I sort an array with strnatcasecmp?
Pass it as the callback to usort: usort($array, 'strnatcasecmp'). Use natcasesort() instead if you need to preserve the array keys.
Can I use strnatcasecmp to compare version numbers?
Only for simple numeric versions. Use version_compare() for real version strings, because it understands pre-release suffixes such as -alpha, -beta and RC that natural ordering treats as plain letters.
More examples
Natural order versus a plain sort
The first array comes back as TRACK 1, Track 10, Track 3, track 20 — uppercase letters sort before lowercase ones and "10" sorts before "3" character by character. The second array comes back as TRACK 1, Track 3, Track 10, track 20, which is the order a reader expects.
<?php
$tracks = ['Track 3', 'track 20', 'TRACK 1', 'Track 10'];
$natural = $tracks;
sort($tracks); // byte order
usort($natural, 'strnatcasecmp'); // human order
print_r($tracks);
print_r($natural);Case-insensitive equality
release-9 is ranked below release-10 because the digit runs are compared numerically. The second call returns 0, showing that case is ignored entirely, so the final check reports that "Build 7" and "build 7" are the same label.
<?php
var_dump(strnatcasecmp('release-9', 'release-10')); // int(-1)
var_dump(strnatcasecmp('RELEASE-10', 'release-10')); // int(0)
var_dump(strnatcasecmp('release-11', 'release-10')); // int(1)
$a = 'Build 7';
$b = 'build 7';
echo strnatcasecmp($a, $b) === 0 ? "same label\n" : "different\n";
Discussion