我想按修改日期对我的图像数组进行排序,以获得在"images"目录中修改的最后15个图像文件的名称。我如何按日期对它们进行排序,并将结果限制在15个以内?
我使用以下代码:
<?php
$extensions = array('jpg', 'jpeg', 'png', 'gif', 'bmp'); // image extensions
$result = array();
$directory = new DirectoryIterator('images'); // directory to scan
foreach ($directory as $fileinfo) {
if ($fileinfo->isFile()) {
$extension = strtolower(pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION));
if (in_array($extension, $extensions)) {
$result[] = $fileinfo->getFilename();
}
}
}
print_r($result);
?>
我试着在打印之前添加这一行,但没有成功:
usort($result, create_function('$a,$b', 'return filemtime($b) - filemtime($a);'));
现在,我不知道如何将其限制在最后15名。
提前感谢大家。
由于您显然希望将结果放在数组中,所以我会像这样做
$allImages = glob(__DIR__ . '/images/*.{jpg,jpeg,gif,png,bmp}', GLOB_BRACE);
usort($allImages, function($a, $b) {
return filemtime($b) - filemtime($a); }
);
$topFifteen = array_slice($allImages, 0, 15);
这将为您提供按MTime排序的所需的15张图像。
备选方案
如果你想不惜任何代价使用Iterator,你可以根据上面的片段使用以下内容:
$allImages = new ArrayIterator(
glob(__DIR__ . '/images/*.{jpg,jpeg,gif,png,bmp}', GLOB_BRACE)
);
$allImages->uasort(function($a, $b) {
return filemtime($b) - filemtime($a); }
);
$topFifteen = new LimitIterator($allImages, 0, 15);
print_r(iterator_to_array($topFifteen));
尽管你并没有从中获得太多好处。事实上,由于涉及到额外的方法调用,这可能会更慢。
如果你想不惜任何代价使用DirectoryTerator/FilesystemIterator,你可以自己定制Iterator:
class LastModifiedIterator extends RegexIterator
{
public function __construct(FilesystemIterator $filesystemIterator, $pattern)
{
parent::__construct(
$this->sortByMTime($filesystemIterator),
$pattern
);
}
private function sortByMTime(FilesystemIterator $filesystemIterator)
{
$allFiles = iterator_to_array($filesystemIterator);
$sortedByMTime = new ArrayIterator($allFiles);
$sortedByMTime->uasort(function(SplFileInfo $a, SplFileInfo $b) {
return $b->getMTime() - $a->getMTime();
});
return $sortedByMTime;
}
public function accept()
{
return $this->current()->isFile() && parent::accept();
}
}
它做两件事:
- 它按MTime对FileSystemIterator中的所有文件进行排序
- 它过滤所有与regex模式不匹配且不是文件的内容
虽然在一个类中同时做这两件事可能不是最好的关注点分离,但我发现在这里做是可以的,除非你在其他地方需要单独做这两项中的任何一项。
你可以这样使用它:
$topFifteenIterator = new LimitIterator(
new LastModifiedIterator(
new FilesystemIterator(__DIR__ . '/images'),
'#.*(jpg|jpeg|gif|png|bmp)$#'
),
0, 15
);
foreach ($topFifteenIterator as $i => $file) {
echo $file, PHP_EOL;
}
无论如何,我会选择第一个。
您也可以将修改日期存储在数组中,以便使用它进行排序。这样可以避免重复的文件访问:
$extensions = array('jpg', 'jpeg', 'png', 'gif', 'bmp'); // image extensions
$result = array();
$directory = new DirectoryIterator('images'); // directory to scan
foreach ($directory as $fileinfo) {
if ($fileinfo->isFile()) {
$extension = strtolower(pathinfo($fileinfo->getFilename(), PATHINFO_EXTENSION));
if (in_array($extension, $extensions)) {
// create array elements with two keys:
$result[] = array(
"filename" => $fileinfo->getFilename(),
"modified_on" => $fileinfo->getMTime()
);
}
}
}
// sort function (descending)
function compare_files($a, $b) {
return $b["modified_on"] - $a["modified_on"];
}
// sort files by descending modification date
usort($result, "compare_files");
// keep 15 most recent files
$result = array_slice($result, 0, 15);
// print
foreach ($result as $fileinfo) {
echo $fileinfo["filename"] . "<br>";
}