Recursively count files using PHP

A simple question for newb and my Google-Fu does not allow me. Using PHP, how can you count the number of files in a given directory, including any subdirectories (and any subdirectories they may have, etc.)? for example, if the directory structure looks like this:

 / Dir_A /  
 /Dir_A/File1.blah  
 / Dir_A / Dir_B /  
 /Dir_A/Dir_B/File2.blah  
 /Dir_A/Dir_B/File3.blah  
 / Dir_A / Dir_B / Dir_C /  
 /Dir_A/Dir_B/Dir_C/File4.blah  
 / Dir_A / Dir_D /  
 /Dir_A/Dir_D/File5.blah

The script should return from "5" for "./Dir_A".

I combined the following, but this did not quite return the correct answer, and I'm not sure why:

 function getFilecount ($ path = '.', $ filecount = 0, $ total = 0) {  
     $ ignore = array ('cgi-bin', '.', '..', '.DS_Store');  
     $ dh = @opendir ($ path);  
     while (false! == ($ file = readdir ($ dh))) {  
         if (! in_array ($ file, $ ignore)) {  
             if (is_dir ("$ path / $ file")) {  
                 $ filecount = count (glob ("$ path / $ file /". "*"));  
                 $ total + = $ filecount;  
                 echo $ filecount;  / * debugging * /
                 echo "$ total";  / * debugging * /
                 echo "$ path / $ file 
"; / * debugging * / getFilecount ("$ path / $ file", $ filecount, $ total); } } } return $ total; }

I am very grateful for any help.

+7
php count recursion
source share
6 answers

This should do the trick:

function getFileCount($path) { $size = 0; $ignore = array('.','..','cgi-bin','.DS_Store'); $files = scandir($path); foreach($files as $t) { if(in_array($t, $ignore)) continue; if (is_dir(rtrim($path, '/') . '/' . $t)) { $size += getFileCount(rtrim($path, '/') . '/' . $t); } else { $size++; } } return $size; } 
+15
source share

Use SPL and then see if you have a bug.

RecursiveDirectoryIterator

Usage example:

 <?php $path = realpath('/etc'); $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST); foreach($objects as $name => $object){ echo "$name\n"; } ?> 

This lists all the files and directories in $ path (including $ path ifself). If you want to omit directories, delete the RecursiveIteratorIterator :: SELF_FIRST part.

Then just use isDir ()

+13
source share

Why are you passing $ filecount? The value of [past] is not used; the only use is "$ total + = $ filecount" and before that you override $ filecount.

You are missing the case when a function encounters a regular (non-dir) file.

Edit: I just noticed a call to glob (). It is not necessary. Anyway, your function recursively affects every file in the entire directory tree. See Reply @Paolo Bergantino.

0
source share

Paolo Bergantino was almost with his code, but the function will still read .DS_Store files, since he made a mistake. Correct code below

 function getFileCount($path) { $size = 0; $ignore = array('.','..','cgi-bin','.DS_Store'); $files = scandir($path); foreach($files as $t) { if(in_array($t, $ignore)) continue; if (is_dir(rtrim($path, '/') . '/' . $t)) { $size += getFileCount(rtrim($path, '/') . '/' . $t); } else { $size++; } } return $size; } 
0
source share

based on Andrew's answer ...

  $path = realpath('my-big/directory'); $objects = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST ); $count=iterator_count($objects); echo number_format($count); //680,642 wooohaah! 

how can I count (not list) thousands and thousands of files. 680 642 files in less than 4.6 seconds actually;)

0
source share

Check the PHP manual for the glob() function: http://php.net/glob

The comments have examples of how to make this recursive.

-one
source share

All Articles