List all files with dates recursively with PHP

Before anyone marks this duplicate, please understand that I searched this site, google and PHP.net searches.

What I want is very simple. I want a list of all files on a website with a date (last modified). I found several scripts that claim to do this, but none of them work.

The best I've found so far is:

header("Pragma: public");
  header("Cache-Control: private");
  header("Content-Type: text/csv");
  header("Content-Disposition: attachment; filename=age-of-files.csv");

  $result = array();
  $handle =  opendir(".");
     while ($datei = readdir($handle))
     {
          if (($datei != '.') && ($datei != '..'))
          {
               $file = "./".$datei;
               if (!is_dir($file))
                    $result[] = $file;
          }
     }
     closedir($handle);
  foreach($result as $r)
    if (file_exists($r))
      echo substr($r,2).",".date ("m-d-Y", filemtime($r))."\r\n"; 

      

This works great for the dircetory the script is running in, but it is not recursive. I need it to keep running in every subdirectory. My goal is to have a sorted list so that I can find files that have changed on or around specific dates.

I'm new to PHP, so bear with me. I've done some research on PHP.net (I see people refer to SPL all the time and I'm not sure what that means or what it is, but maybe this is a bunch of PHP standard classes?) And it seems to me that I need to somehow use the RecursiveDirectoryIterator.

I found this script that looks great on paper, but running it on my site gives a blank white screen.

try
{
        /*** freds home directory ***/
        $rdi = new recursiveDirectoryIterator('/',  FilesystemIterator::SKIP_DOTS | FilesystemIterator::UNIX_PATHS);
        $it = new recursiveIteratorIterator( $rdi );
        while( $it->valid())
        {
                if( !$it->isDir() )
                {
                        echo $it->current().' '.date('Y m d H:i:s', $it->getATime() )."\n";
                }

                /*** move to the next element ***/
                $it->next();
        }
}
catch(Exception $e)
{
        /*** echo the error message ***/
        echo $e->getMessage();
}

      

I'd rather use the first script, as I like that it creates a csv file (easy to sort), but I'm not sure how to come to terms with these two. Can anyone advise me on how to include RDI in the first script?

+3


source to share


3 answers


Here is a little code that I found working very well



$rdi = new RecursiveDirectoryIterator("path/"); // The directory here
$rii = new RecursiveIteratorIterator($rdi);

foreach ($rii as $filename=>$cur) {
    echo $cur.' '.date('Y m d H:i:s', $cur->getATime() )."<br/>";
}

      

0


source


Try something like this, similar to the second example you provided:

<?php

$path = __DIR__;

if (!is_dir($path)) {
    throw new RuntimeException(sprintf('Path %s does not exist!', $path));
}

if (!is_readable($path)) {
    throw new RuntimeException(sprintf('Path %s is not readable!', $path));
}

$iterator = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($path)
);

$files = [];

foreach ($iterator as $fileInfo) {
    if ($fileInfo->isFile()) {
        $files[] = [
            $fileInfo->getFilename(),
            dirname($fileInfo->getPathname()),
            date('c', $fileInfo->getMTime())
        ];
    }
}

print_r($files);

      

Given the approximate file structure:

enter image description here

This gives:

Array
(
    [0] => Array
        (
            [0] => .DS_Store
            [1] => /private/tmp/rec
            [2] => 2015-08-08T08:28:33+00:00
        )

    [1] => Array
        (
            [0] => .DS_Store
            [1] => /private/tmp/rec/0
            [2] => 2015-08-08T08:28:33+00:00
        )

    [2] => Array
        (
            [0] => 0.1.txt
            [1] => /private/tmp/rec/0/0.1
            [2] => 2015-08-08T08:27:58+00:00
        )

    [3] => Array
        (
            [0] => 0.txt
            [1] => /private/tmp/rec/0
            [2] => 2015-08-08T08:27:58+00:00
        )

    [4] => Array
        (
            [0] => .DS_Store
            [1] => /private/tmp/rec/1
            [2] => 2015-08-08T08:28:33+00:00
        )

    [5] => Array
        (
            [0] => .DS_Store
            [1] => /private/tmp/rec/1/1.1
            [2] => 2015-08-08T08:28:27+00:00
        )

    [6] => Array
        (
            [0] => 1.1.txt
            [1] => /private/tmp/rec/1/1.1
            [2] => 2015-08-08T08:27:58+00:00
        )

    [7] => Array
        (
            [0] => 1.txt
            [1] => /private/tmp/rec/1
            [2] => 2015-08-08T08:27:58+00:00
        )

    [8] => Array
        (
            [0] => rec.php
            [1] => /private/tmp/rec
            [2] => 2015-08-08T08:48:30+00:00
        )

)

      



Each match is stored as a sub-array element containing:

  • File name
  • Current dirpath
  • Time of last modification

It performs some additional checks to ensure it is viewable $path

.

Now that you have the result set $files

in an array, you should be able to reuse some of the code in the first example to output it as a CSV file.

Hope it helps :)

+1


source


If anyone is interested, this is what I ran into. It combines the simplicity and efficiency of the first answer with the csv of the first example in my question. When I open the csv file in excel I can sort by day easily.

The reason I needed this was to help identify some malware on one of my sites. With a list of all files, I can sort by date and search for files that were added on suspicious dates. Or, conversely, if I found a known threat on a certain day, I can easily see what other files were changed on that day / time. It helped me a lot, finally ridding my site of a constant infection. It kept coming to life because I was unable to delete all files. Using this simple script, I finally found the backdoor wrapper installed. Phew!

Many thanks to both answering machines! :)

<?php
header("Pragma: public");
header("Cache-Control: private");
header("Content-Type: text/csv");
header("Content-Disposition: attachment; filename=age-of-files.csv");

$rdi = new RecursiveDirectoryIterator("."); // The directory here
$rii = new RecursiveIteratorIterator($rdi);

foreach ($rii as $filename=>$cur) {
    echo $cur.', '.date('m-d-Y', $cur->getATime() ).', '.date('H:i:s', $cur->getATime() )."\r\n";
}
?>

      

+1


source







All Articles