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";
}
我正在检索目录中的照片文件列表并将其回显到网页中,以便可以为任何相册自动创建该页面。
以下工作正常,但结果是照片不是按自然顺序排列的,这正是我想要的:
<?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 仅适用于字符串数组。
你可以用
替换 natsortusort($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";
}