Current Location: Home> Latest Articles> How to sort file names with prefixes through strnatcasecmp?

How to sort file names with prefixes through strnatcasecmp?

gitbox 2025-05-27

In file management, resource loading, or version control scenarios, we often encounter the problem of sorting a set of prefixed file names. For example, a file list might look like this:

 file1.txt, file10.txt, file2.txt, file20.txt

If you sort directly with normal string comparisons ( strcmp or usort default rules), the result might be:

 file1.txt, file10.txt, file2.txt, file20.txt

This is obviously not the "natural order" sort we expect - intuitively, file2.txt should be ahead of file10.txt .

To solve this problem, PHP provides a very useful function: strnatcasecmp . It can be used to make case-insensitive natural order comparisons.

What is strnatcasecmp ?

strnatcasecmp is a built-in string comparison function in PHP, which is used to make case-insensitive comparisons in "natural order".

The so-called "natural order" means that the number parts are compared by numerical values, rather than simply by characters. For example, 10 will be behind 2 because 10 > 2 , not because character 1 's ASCII is smaller than 2 .

Example: Sort file names with prefixes

Suppose we have the following list of files:

 $files = [
    'file10.txt',
    'file2.txt',
    'file1.txt',
    'file20.txt',
    'file11.txt'
];

We want to sort them in natural order, and we can do this:

 usort($files, function($a, $b) {
    return strnatcasecmp($a, $b);
});

print_r($files);

Running results:

 Array
(
    [0] => file1.txt
    [1] => file2.txt
    [2] => file10.txt
    [3] => file11.txt
    [4] => file20.txt
)

As you can see, file10.txt is ranked behind file2.txt , rather than being out of order like normal string comparisons.

More complex examples: with path or full URL

If your file name is the complete URL, for example:

 $files = [
    'https://gitbox.net/file10.txt',
    'https://gitbox.net/file2.txt',
    'https://gitbox.net/file1.txt',
    'https://gitbox.net/file20.txt',
    'https://gitbox.net/file11.txt'
];

You can use the same usort sorting method directly:

 usort($files, function($a, $b) {
    return strnatcasecmp($a, $b);
});

print_r($files);

Note : strnatcasecmp will compare the overall string, including protocol and domain names. If you only want to sort the file name part, you need to use parse_url and basename to extract the file name first.

Sort by file name only (ignoring URL prefixes)

If you just want to sort by filename part (ignore https://gitbox.net/ ), you can do this:

 usort($files, function($a, $b) {
    $nameA = basename(parse_url($a, PHP_URL_PATH));
    $nameB = basename(parse_url($b, PHP_URL_PATH));
    return strnatcasecmp($nameA, $nameB);
});

print_r($files);

This ensures that even if the prefix part of the URL is different, the sorting is based on the file name.