Skip to content
Advertisement

PHP DirectoryIterator with natsort

I am retrieving a list if photo files from a directory and echoing into a web page so that the page can be created automatically for any photo album.

The following is working fine, but the result is that the photos are not in natural order which is what I’d prefer:

<?php
$year = '2021/';
$folder = 'league/';
$n = 1;
$directory = $_SERVER['DOCUMENT_ROOT'].'/events/'.$folder.$year.'images/photos/album/medium';
$numFiles = count(scandir($directory))-2;
$files = new DirectoryIterator($directory);

natsort($files);
foreach ($files as $file) {
if($file->isDot()) continue;
echo '<div class="mySlides">'.PHP_EOL;
echo '<div class="numbertext">'.$n.' / '.$numFiles.'</div>'.PHP_EOL;
echo '<a target="_blank" href="/events/'.$folder.$year.'images/photos/album/large/'.$file->getFilename().'"><img src="/events/'.$folder.$year.'images/photos/album/medium/'.$file->getFilename().'" alt="'.$file->getFilename().'" style="width:100%"></a>'.PHP_EOL;
echo '</div>'.PHP_EOL.PHP_EOL;
$n++;
}

?>

Advertisement

Answer

The sort category of functions only operate on arrays, but you can easily convert an iterator to an array with iterator_to_array(). However, since DirectoryIterator::current() returns the iterator itself, instead of SplFileInfo objects for each file, this will lead to undesired results.

My suggestion would therefore be to use FilesystemIterator (which extends DirectoryIterator), because it is a little more flexible and by default makes current() return SplFileInfo objects instead of the iterator itself and as a bonus skips dots as well.

Putting this all together then becomes:

$files = iterator_to_array(new FilesystemIterator($directory));

usort($files, function($a, $b)
{
  return strnatcmp($a->getFilename(), $b->getFilename());
});

foreach($files as $file) {
  echo $file->getFilename() . "n";
}
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement