PHP 带有 natsort 的 DirectoryIterator

PHP DirectoryIterator with natsort

我正在检索目录中的照片文件列表并将其回显到网页中,以便可以为任何相册自动创建该页面。

以下工作正常,但结果是照片不是按自然顺序排列的,这正是我想要的:

<?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++;
}

?>

natsort 仅适用于字符串数组。

你可以用

替换 natsort
usort($files, function($a, $b)
{
    return strnatcmp($a->getFilename(), $b->getFilename());
});
$iterator = new DirectoryIterator($directory);

// Create an array with filenames as key and iterator index as value
$filenames = [];
foreach ($iterator as $index => $item) {
  $filenames[$item->getFilename()] = $index;
}

// Sort the filenames with 'natural compare'
uksort($filenames, static function ($filename1, $filename2) {
  return strnatcmp($filename1, $filename2);
});

// Filter out working directory and parent directory
$filenames = array_filter($filenames, static function ($filename) {
  return $filename !== '.' && $filename !== '..';
}, ARRAY_FILTER_USE_KEY);

// Do something with each DirectoryIterator entry
foreach ($filenames as $filename => $index) {
  $iterator->seek($index);
  ...
  echo $iterator->getFilename() . "\n";
  echo $iterator->getPathname() . "\n";
  etc.
  ...
}

函数的排序类别只对数组进行操作,但您可以使用 iterator_to_array() 轻松地将迭代器转换为数组。但是,由于 DirectoryIterator::current() return 是迭代器本身,而不是每个文件的 SplFileInfo 个对象,这将导致不希望的结果。

因此,我的建议是使用 FilesystemIterator(它扩展了 DirectoryIterator),因为它更灵活一些,默认情况下 current() return SplFileInfo 对象而不是迭代器本身,并且作为奖励也会跳过点。

把这些放在一起就变成了:

$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";
}