1

I am looking for code which lists the five most recent files in a directory recursively.

This is non-recursive code, and would be perfect for me if it was recursive:

<?php

$show = 0; // Leave as 0 for all
$dir = 'sat/'; // Leave as blank for current

if($dir) chdir($dir);
$files = glob( '*.{html,php,php4,txt}', GLOB_BRACE );
usort( $files, 'filemtime_compare' );

function filemtime_compare( $a, $b )
{
    return filemtime( $b ) - filemtime( $a );
}
$i = 0;
foreach ( $files as $file )
{
    ++$i;
    if ( $i == $show ) break;
    echo $file . ' - ' . date( 'D, d M y H:i:s', filemtime($file) ) . '<br />' . "\n";  /* This is the output line */
}
?>

It is possible to modify it to scan directories recursively?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Peter
  • 65
  • 3
  • 6

4 Answers4

2

This was my first version (tested, working):

function latest($searchDir, array $files = array()) {
    $search = opendir($searchDir);

    $dirs = array();
    while($item = readdir($search)) {
        if ($item == '.' || $item == '..') { continue; }
        if (is_dir($searchDir.'/'.$item)) {
            $dirs[] = $searchDir.'/'.$item;
        }
        if (is_file($searchDir.'/'.$item)) {
            $ftime = filemtime($searchDir.'/'.$item);
            $files[$ftime] = $searchDir.'/'.$item;
        }
    }
    closedir($search);
    if (count($dirs) > 0) {
        foreach ($dirs as $dir) {
            $files += latest($dir,$files);
        }
    }
    krsort($files);
    $files = array_slice($files, 0, 5, true);
    return $files;
}

But I like byte's usage of glob(), so here is a slightly modified version of his to return the same format:

function top5modsEx($dir) {
    $mods = array();
    foreach (glob($dir . '/*') as $f) {
        $mods[filemtime($f)] = $f;
    }
    krsort($mods);
    return array_slice($mods, 0, 5, true);
}

This returns the time (UNIX Timestamp format) that the file was modified as the key of the element in the array.

Dereleased
  • 9,939
  • 3
  • 35
  • 51
  • Working like a charm! Is there any way to exclude files from the search? – Peter May 30 '10 at 13:29
  • || $item == 'exclude this' --- this is the solution. Thank you very much again! – Peter May 30 '10 at 13:35
  • Trying to run this on a windows to help with upgrades to a script and the first script works like it should. However, the second one doesn't list anything recursively and just does the initial directory. – Dawson Irvine Jan 15 '22 at 22:06
1

This is pretty quick and dirty, and untested, but might get you started:

function top5mods($dir)
{
  $mods = array();
  foreach (glob($dir . '/*') as $f) {
    $mods[] = filemtime($f);
  }
  sort($mods);
  $mods = array_reverse($mods);
  return array_slice($mods, 0, 5);
}
dreadwail
  • 15,098
  • 21
  • 65
  • 96
0

Check out this solution in the PHP manual.

dnagirl
  • 20,196
  • 13
  • 80
  • 123
  • Link-only answers to documentation are hints that can be posted as comments under the question. This answer is vague and low-value. – mickmackusa Apr 16 '20 at 13:33
0

Edit : Sorry I didn't see the part "recursively".

To get RECENTS files first (html for example), please sort like this with anonymous function :

$myarray = glob("*.*.html");
usort($myarray, function($a,$b){
  return filemtime($b) - filemtime($a);
});

And to get it recursively you can :

function glob_recursive($pattern, $flags = 0) {
    $files = glob($pattern, $flags);
    foreach (glob(dirname($pattern).'/*', GLOB_ONLYDIR|GLOB_NOSORT) as $dir) {
        $files = array_merge($files, glob_recursive($dir.'/'.basename($pattern), $flags));
    }
    return $files;
}

So, replace then the glob function by :

$myarray = glob_recursive("*.*.html");
usort($myarray, function($a,$b){
  return filemtime($b) - filemtime($a);
});
Medhi
  • 2,656
  • 23
  • 16
  • Please read the question requirements before posting an answer so that you know exactly what a proposed solution MUST do. Did you test your suggestion before posting it? – mickmackusa Apr 16 '20 at 13:36
  • You are expected to announce where you source code from when you are not the author. This is plagarism otherwise. – mickmackusa Apr 16 '20 at 14:00
  • this in one my projets... but feel free to delete it if you want :) – Medhi Apr 16 '20 at 14:40
  • I have linked several posts (as comments under the question) in Stackoverflow which are using the exact same custom function. I am also not sure that you have the sorting correct. Did you test your answer? – mickmackusa Apr 16 '20 at 14:41
  • I've tested it this afternoon MickMackUSA. If you inverse $a & $b, you have oldest first. Thank you for your time and please, tell me how different can I offer an sorting function for get files by timestamp ? – Medhi Apr 16 '20 at 14:47
  • Proof that you are sorting ASC instead of DESC as desired by the OP: https://3v4l.org/DGsc5 The most recent files will have the highest unix stamp. The OP doesn't need help with this though -- the correct sorting is already in the question. This question is asking about the recursive search for files. – mickmackusa Apr 16 '20 at 14:57
  • Weird, I past the wrong line indeed ! I just doublerse check on my website where I display latest uploaded images :) thanks for your time. – Medhi Apr 16 '20 at 15:23