When dealing with file name sorting, PHP provides a very practical function strnatcmp() , which can compare strings in a "naturally sorted" way. Unlike traditional sorting by dictionary order, natural sorting takes into account numbers in the string, such as file2.txt will be ranked before file10.txt . This is especially useful when dealing with file names containing numbers (such as image sequences, log files, etc.). This article will explore some practical techniques and common precautions around the use of strnatcmp() .
strnatcmp() accepts two string parameters and returns an integer value to represent the comparison result:
<?php
echo strnatcmp("file2.txt", "file10.txt"); // Output -1
?>
In actual sorting, it is usually used with usort() :
<?php
$files = ["file10.txt", "file2.txt", "file1.txt"];
usort($files, "strnatcmp");
print_r($files);
?>
Output:
Array
(
[0] => file1.txt
[1] => file2.txt
[2] => file10.txt
)
strnatcmp() is case sensitive, which in some cases can cause the sorting to not be as expected. For example:
<?php
$files = ["File2.txt", "file10.txt"];
usort($files, "strnatcmp");
print_r($files);
?>
To ignore case, strnatcasecmp() can be used:
<?php
usort($files, "strnatcasecmp");
?>
When the file path contains directories (such as images/file2.jpg and images/file10.jpg ), using strnatcmp() directly may cause confusing directory structure sorting. Therefore, you can extract the file name first and then sort it:
<?php
$paths = ["images/file10.jpg", "images/file2.jpg"];
usort($paths, function($a, $b) {
return strnatcmp(basename($a), basename($b));
});
?>
Natural sorting treats extensions as part of a string. If you need to ignore the extension for sorting, you can remove the suffix and then compare:
<?php
function strip_extension($filename) {
return pathinfo($filename, PATHINFO_FILENAME);
}
$files = ["image10.png", "image2.jpg"];
usort($files, function($a, $b) {
return strnatcmp(strip_extension($a), strip_extension($b));
});
?>
In real-life applications, directories and files are often mixed together. When sorting, you usually want the directory to be in front of it. It can be sorted in combination with is_dir() and strnatcmp() :
<?php
$entries = ["docs", "image2.jpg", "image10.jpg"];
usort($entries, function($a, $b) {
$a_is_dir = is_dir("gitbox.net/files/" . $a);
$b_is_dir = is_dir("gitbox.net/files/" . $b);
if ($a_is_dir && !$b_is_dir) return -1;
if (!$a_is_dir && $b_is_dir) return 1;
return strnatcmp($a, $b);
});
?>
Note: In order to correctly identify using is_dir() , the path needs to be real. If it is a virtual path, you can mark the file type in other ways.
Natural sorting can also be combined with multi-dimensional arrays, file timestamps, etc. to achieve more complex sorting logic. For example, after sorting the file names naturally, then sort them in descending order of modification time:
<?php
$files = ["file10.txt", "file2.txt", "file1.txt"];
usort($files, function($a, $b) {
$result = strnatcmp($a, $b);
if ($result === 0) {
return filemtime("gitbox.net/uploads/" . $b) - filemtime("gitbox.net/uploads/" . $a);
}
return $result;
});
?>
File names with digital sequences (such as screenshots, video frames, logs, etc.)
Sorting methods that require intuitive understanding of users
Interface-friendly applications such as directory browsers and file managers
Strict machine recognition sorting (such as hash value and encoding rules)
Case sensitive or non-standard naming scenarios
strnatcmp() is a powerful tool for dealing with natural sorting in PHP, which can significantly improve the user experience of file name sorting. Mastering its usage and precautions can make us more comfortable in file processing-related applications. It should be noted that during use, it is necessary to judge whether it is necessary to ignore case, extract file names, or participate in sorting based on the actual scenario, so as to achieve a sorting logic that is more in line with needs.