在一个目录中获取最后修改的文件

19

有没有一种方法可以仅选择目录中的最后一个文件(扩展名为jpg|png|gif)?

还是我必须解析整个目录并使用filemtime进行检查?

4个回答

50

是的,你需要全部阅读它们。但是由于目录访问已被缓存,所以你不需要太担心。

$files = array_merge(glob("img/*.png"), glob("img/*.jpg"));
$files = array_combine($files, array_map("filemtime", $files));
arsort($files);

$latest_file = key($files);

3
不是的,这只是使用具有内置文件名过滤器的 scandir()。我曾经实现了一个 PHP4 的重新实现。真正的问题在于使用了两个 glob 函数。在您的情况下,更快的方法是使用 glob("img/*.{png,jpg,gif}", GLOB_BRACE) - mario
1
是的,scandir返回所有条目。但glob已经进行了过滤。readdir方法的不同之处在于您需要使用更多的php/system调用以逐个停止和继续执行。 - mario
glob在编译后的C代码中执行循环,而readdir需要一个较慢的PHP while循环。 - mario
你有特定的原因来进行微观优化吗?否则,我建议使用实际的xdebug分析器运行。(我打赌20美分是全局匹配。) - mario
在 hearsay 和假设的基础上优化 PHP 代码是行不通的。请参考 http://www.xdebug.org/docs/profiler。 - mario

6
我不记得曾经见过能够做你所要求的功能的函数。
因此,我认为你将不得不浏览所有(至少jpg/png/gif)文件,并搜索每个文件的最后修改日期。
这里有一个可能的解决方案,基于SPL的DirectoryIterator类:
$path = null;
$timestamp = null;

$dirname = dirname(__FILE__);
$dir = new DirectoryIterator($dirname);
foreach ($dir as $fileinfo) {
    if (!$fileinfo->isDot()) {
        if ($fileinfo->getMTime() > $timestamp) {
            // current file has been modified more recently
            // than any other file we've checked until now
            $path = $fileinfo->getFilename();
            $timestamp = $fileinfo->getMTime();
        }
    }
}

var_dump($path);

当然,您也可以使用readdir()和其他相应的函数来完成同样的事情。

PHP 应该内置这样的函数,这样我们就不需要解析所有的目录了。在我看来。 - dynamic
编写这个函数并不难;-);;;但你需要的似乎有点特定,所以核心开发人员可能不想在PHP本身实现这样的函数。 - Pascal MARTIN
尽管你没有检查扩展名,但我会接受这个的,因为我确信readdir(或其等效物)比glob+另一个解析更快。 - dynamic
哎呀,是的,我忘记了扩展名部分;对此感到抱歉 :-( 很遗憾 SplFileInfo::getExtension 方法只能在 PHP >= 5.3.6 版本以上使用 (http://fr2.php.net/manual/en/splfileinfo.getextension.php)。 - Pascal MARTIN
我将只使用一个简单的readdir和preg_match(/\.(jpg|gif)$/i,$file) - dynamic
@Pascal MARTIN,是的,这很遗憾,但至少现在已经有了。此外,一个选项是将DirectoryIterator(或FilesystemIterator)包装在RegexIterator中,以仅迭代所需的图像文件。还有一个GlobIterator,但在这里没有多大用处。 - salathe

2
function listdirfile_by_date($path)
{
    $dir = opendir($path);
    $list = array();
    while($file = readdir($dir))
    {
        if($file != '..' && $file != '.')
        {
            $mtime = filemtime($path . $file) . ',' . $file;
            $list[$mtime] = $file;
        }
    }
    closedir($dir);
    krsort($list);

    foreach($list as $key => $value)
    {
        return $list[$key];
    }
    return '';
}

2

Use this code:

<?php
// outputs e.g.  somefile.txt was last modified: December 29 2002 22:16:23.

$filename = 'somefile.txt';
if (file_exists($filename)) {
    echo "$filename was last modified: " . date ("F d Y H:i:s.", filemtime($filename));
}
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接