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];