PHP按文件名中的数字排序数组

I am working on a photo gallery that automatically sorts the photos based on the numbers of the file name.

I have the following code:

//calculate and sort 
$totaal = 0;
if($handle_thumbs = opendir('thumbs')){
    $files_thumbs = array();
    while(false !== ($file = readdir($handle_thumbs))){
        if($file != "." && $file != ".."){
            $files_thumbs[] = $file;
            $totaal++;
        }
    }
    closedir($handle_thumbs);
}
sort($files_thumbs);


//reset array list
$first = reset($files_thumbs);
$last = end($files_thumbs);
//match and split filenames from array values - image numbers
preg_match("/(\d+(?:-\d+)*)/", "$first", $matches);
$firstimage = $matches[1];
preg_match("/(\d+(?:-\d+)*)/", "$last", $matches);
$lastimage = $matches[1];

But when i have file names like photo-Aname_0333.jpg, photo-Bname_0222.jpg, it does start with the photo-Aname_0333 instead of the 0222.

How can i sort this by the filename numbers?

usort is a php function to sort array using values. usort needs a callback function that receives 2 values.

In the callback, depending of your needs, you will be return the result of the comparision 1, 0 or -1. For example to sort the array asc, I return -1 when the firts value of the callback is less than second value.

In this particular case I obtain the numbers of the filename, and compare it as string, is not necesary to cast as integer.

<?php

$photos=[
    'photo-Bname_0222.jpg',
    'photo-Aname_0333.jpg', 
    'photo-Cname_0111.jpg', 

];

usort($photos, function ($a, $b) {

    preg_match("/(\d+(?:-\d+)*)/", $a, $matches);
    $firstimage = $matches[1];
    preg_match("/(\d+(?:-\d+)*)/", $b, $matches);
    $lastimage = $matches[1];

    if ($firstimage == $lastimage) {
        return 0;
    }
    return ($firstimage < $lastimage) ? -1 : 1;
});

print_r($photos);

It sorts alphabetically because you use sort() on the filename. The 2nd part of your code does nothing.

You might want to take a look at usort http://php.net/manual/en/function.usort.php You can do something like

function cmp($a, $b) {
    if ($a == $b) {
        return 0;
    }
    preg_match('/(\d+)\.\w+$/', $a, $matches);
    $nrA = $matches[1];
    preg_match('/(\d+)\.\w+$/', $b, $matches);
    $nrB = $matches[1];

    return ($nrA < $nrB) ? -1 : 1;
}

usort($files_thumb, 'cmp');

Also, I'm not sure about your regex, consider a file named "abc1234cde2345xx". The one I used takes the last digits before a file extension at the end. But it all depends on your filenames.

sort(array,sortingtype) , you have to set the second parameter of the sort() function to 1 so it will sort items numerically 



 //calculate and sort 
$totaal = 0;
if($handle_thumbs = opendir('thumbs')){
    $files_thumbs = array();
    while(false !== ($file = readdir($handle_thumbs))){
        if($file != "." && $file != ".."){
            $files_thumbs[] = $file;
            $totaal++;
        }
    }
    closedir($handle_thumbs);
}
sort($files_thumbs,1);
//reset array list
$first = reset($files_thumbs);
$last = end($files_thumbs);
//match and split filenames from array values - image numbers
preg_match("/(\d+(?:-\d+)*)/", "$first", $matches);
$firstimage = $matches[1];
preg_match("/(\d+(?:-\d+)*)/", "$last", $matches);
$lastimage = $matches[1];