如何使用PHP通过mdate对图像进行排序


How can I sort images by mdate with PHP?

我想按修改日期对我的图像数组进行排序,以获得在"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();
    }
}

它做两件事:

  1. 它按MTime对FileSystemIterator中的所有文件进行排序
  2. 它过滤所有与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>";    
}