PHP подсчитывает количество файлов в каталоге и подкаталоге

Мне нужно получить общее количество JPG-файлов в указанном каталоге, включая ВСЕ его подкаталоги. Нет суб-подкаталогов.

Структура выглядит так:

 dir1 /
 2 файла  
    subdir 1 /
        8 файлов

total dir1 = 10 файлов

 dir2 / 
     5 файлов  
     subdir 1 / 
         2 файла  
     subdir 2 / 
         8 файлов

total dir2 = 15 файлов

У меня есть эта функция, которая не работает нормально, поскольку она учитывает только файлы в последнем подкаталоге, а сумма в 2 раза больше, чем фактическое количество файлов. (выводит 80, если у меня 40 файлов в последнем поддиректоре)

public function count_files($path) { global $file_count; $file_count = 0; $dir = opendir($path); if (!$dir) return -1; while ($file = readdir($dir)) : if ($file == '.' || $file == '..') continue; if (is_dir($path . $file)) : $file_count += $this->count_files($path . "/" . $file); else : $file_count++; endif; endwhile; closedir($dir); return $file_count; } 

Для удовольствия я взбивал это вместе:

 class FileFinder { private $onFound; private function __construct($path, $onFound, $maxDepth) { // onFound gets called at every file found $this->onFound = $onFound; // start iterating immediately $this->iterate($path, $maxDepth); } private function iterate($path, $maxDepth) { $d = opendir($path); while ($e = readdir($d)) { // skip the special folders if ($e == '.' || $e == '..') { continue; } $absPath = "$path/$e"; if (is_dir($absPath)) { // check $maxDepth first before entering next recursion if ($maxDepth != 0) { // reduce maximum depth for next iteration $this->iterate($absPath, $maxDepth - 1); } } else { // regular file found, call the found handler call_user_func_array($this->onFound, array($absPath)); } } closedir($d); } // helper function to instantiate one finder object // return value is not very important though, because all methods are private public static function find($path, $onFound, $maxDepth = 0) { return new self($path, $onFound, $maxDepth); } } // start finding files (maximum depth is one folder down) $count = $bytes = 0; FileFinder::find('.', function($file) use (&$count, &$bytes) { // the closure updates count and bytes so far ++$count; $bytes += filesize($file); }, 1); echo "Nr files: $count; bytes used: $bytes\n"; 

Вы передаете базовый путь, найденный обработчик и максимальную глубину каталога (-1 для отключения). Найденный обработчик – это функция, которую вы определяете снаружи, она получает имя пути относительно пути, указанного в функции find() .

Надеюсь, это имеет смысл и поможет вам 🙂

Вы можете сделать это так, используя RecursiveDirectoryIterator

 <?php function scan_dir($path){ $ite=new RecursiveDirectoryIterator($path); $bytestotal=0; $nbfiles=0; foreach (new RecursiveIteratorIterator($ite) as $filename=>$cur) { $filesize=$cur->getSize(); $bytestotal+=$filesize; $nbfiles++; $files[] = $filename; } $bytestotal=number_format($bytestotal); return array('total_files'=>$nbfiles,'total_size'=>$bytestotal,'files'=>$files); } $files = scan_dir('./'); echo "Total: {$files['total_files']} files, {$files['total_size']} bytes\n"; //Total: 1195 files, 357,374,878 bytes ?> 

если кто-то хочет подсчитать общее количество файлов и каталогов.

Показывать / подсчитывать общее количество реестров и поддиректориев

 find . -type d -print | wc -l 

Показывать / подсчитывать общее количество файлов в главном и вспомогательном каталоге

 find . -type f -print | wc -l 

Показывать / подсчитывать только файлы из текущего каталога (без sub dir)

 find . -maxdepth 1 -type f -print | wc -l 

Показывать / подсчитывать общие каталоги и файлы в текущем каталоге (без вспомогательных файлов)

 ls -1 | wc -l 
 error_reporting(E_ALL); function printTabs($level) { echo "<br/><br/>"; $l = 0; for (; $l < $level; $l++) echo "."; } function printFileCount($dirName, $init) { $fileCount = 0; $st = strrpos($dirName, "/"); printTabs($init); echo substr($dirName, $st); $dHandle = opendir($dirName); while (false !== ($subEntity = readdir($dHandle))) { if ($subEntity == "." || $subEntity == "..") continue; if (is_file($dirName . '/' . $subEntity)) { $fileCount++; } else //if(is_dir($dirName.'/'.$subEntity)) { printFileCount($dirName . '/' . $subEntity, $init + 1); } } printTabs($init); echo($fileCount . " files"); return; } printFileCount("/var/www", 0); 

Просто проверено, оно работает. Но выравнивание результатов плохое, логические работы

А для каждой петли можно было сделать трюк более быстро 😉

Как я помню, opendir происходит из класса SplFileObject, который является классом RecursiveIterator, Traversable, Iterator, SeekableIterator, поэтому вам не нужны циклы while, если вы используете стандартную библиотеку PHP SPL для извлечения всего количества изображений даже в подкаталоге ,

Но прошло какое-то время, когда я не использовал PHP, чтобы совершить ошибку.