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

时间:2015-12-20 09:40:59

标签: php arrays sorting

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

?> 

我尝试在print_r之前添加这一行,但它确实无效:

usort($result, create_function('$a,$b', 'return filemtime($b) - filemtime($a);'));

另外,我不知道如何将它限制在过去的15年。

提前全部谢谢。

2 个答案:

答案 0 :(得分:1)

因为你显然想要在数组中得到结果,所以我会这样做

    $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张图像。

替代

如果您想不惜任何代价使用迭代器,您可以根据上面的代码段使用以下内容:

$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));

虽然你没有从中获得太多收益。实际上,由于涉及额外的方法调用,这可能会更慢。

如果您想不惜任何代价使用DirectoryIterator / FilesystemIterator,您可以自己创建自定义迭代器:

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. 它会过滤与正则表达式模式不匹配的所有内容,而不是文件
  3. 虽然在一个班级中做两件事可能不是最好的关注点,但我觉得这样做是可以的,除非你在其他地方另外需要这两个中的任何一个。

    你可以像这样使用它:

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

    无论如何,我会选择第一个。

答案 1 :(得分:0)

您也可以将修改日期存储在数组中,以便将其用于排序。这样可以避免重复的文件访问:

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