strnatcasecmp

Compares two strings in human "natural" order, ignoring letter case.

Signature
strnatcasecmp(string $string1, string $string2): int
  • Added in PHP 4.0

Parameters

ParameterTypeDescription
$string1stringThe first string.
$string2stringThe 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

Try it yourself
Loading editor…
Press Run to execute the code.

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.

Example · php
<?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.

Example · php
<?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

  • Be the first to comment on this lesson.