19

Is there a way to select only the last file in a directory (with the extensions jpg|png|gif?)

Or do I have to parse the entire directory and check using filemtime?

Amal Murali
  • 75,622
  • 18
  • 128
  • 150
dynamic
  • 46,985
  • 55
  • 154
  • 231

4 Answers4

50

Yes you have to read through them all. But since directory accesses are cached, you shouldn't really worry about it.

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

$latest_file = key($files);
Nux
  • 9,276
  • 5
  • 59
  • 72
mario
  • 144,265
  • 20
  • 237
  • 291
  • 3
    No. It's just a scandir() with a builtin filename filter. (I wrote a PHP4 reimplementation once). The real problem here is using two globs. It's quicker to use `glob("img/*.{png,jpg,gif}", GLOB_BRACE)` in your case. – mario Mar 27 '11 at 10:12
  • 1
    True, scandir returns *all* entries. But glob filters it down already. The difference in the readdir approach is just that you do it in a stop-and-go fashion with more php/system calls. – mario Mar 27 '11 at 10:59
  • glob does the looping in compiled C code, while readdir requires a slower PHP while loop. – mario Mar 27 '11 at 11:18
  • Do you have a specific reason to microoptimize this? Else I would suggest using an actual xdebug profiler run. (I'm betting 20¢ on glob.) – mario Mar 27 '11 at 11:19
  • http://www.xdebug.org/docs/profiler Optimizing PHP code on hearsay and assumptions won't get you any far. – mario Mar 27 '11 at 11:31
6

I don't remember having ever seen a function that would do what you ask.

So, I think you will have to go through all (at least jpg/png/gif) files, and search for the last modification date of each of them.


Here's a possible solution, based on the DirectoryIterator class of the SPL :

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


Of course, you could also do the same thing with readdir() and other corresponding functions.

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
  • php should have built-in such a function so we don't need to parse all dir .. imo – dynamic Mar 27 '11 at 10:10
  • Writing this function is not that hard ;-) ;;; and you need seems a bit specific, so it might be understandable for core-developers to not want to implement such a function in PHP itself. – Pascal MARTIN Mar 27 '11 at 10:20
  • even tho you didn't checked for exstension lol i am going to accept this because i am sure readdir (or this equivalent) is faster than a glob + another parse – dynamic Mar 27 '11 at 11:32
  • Oops, yep, I forgot the extension part ; sorry about that :-( too bad the `SplFileInfo::getExtension` method is only available with PHP >= 5.3.6 ( http://fr2.php.net/manual/en/splfileinfo.getextension.php ) – Pascal MARTIN Mar 27 '11 at 11:33
  • i will just use to a simple readdir with a `preg_match(/\.(jpg|gif)$/i,$file)` – dynamic Mar 27 '11 at 11:36
  • @Pascal MARTIN, yes that's a shame but at least it's in there now. Also, an option would have been to wrap the `DirectoryIterator` (or, `FilesystemIterator`) in a `RegexIterator` to only iterate over the image files wanted. There's also a `GlobIterator`, which wouldn't have been much use here. – salathe Mar 27 '11 at 12:30
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 '';
}
Waqar Alamgir
  • 9,828
  • 4
  • 30
  • 36
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));
}
?>