PHP目录迭代器与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++;
}

?比;

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

因此,我的建议是使用FilesystemIterator(扩展DirectoryIterator),因为它更灵活一些,默认情况下使current()返回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";
}

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.
...
}

最新更新