Рекурсивный подсчет файлов с помощью PHP - PullRequest
8 голосов
/ 13 марта 2009

Простой вопрос для новичка, и мой Google-Fu подводит меня. Используя PHP, как вы можете подсчитать количество файлов в данном каталоге, включая любые подкаталоги (и любые подкаталоги, которые они могут иметь, и т. Д.)? например если структура каталогов выглядит следующим образом:

/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

Скрипт должен возвращаться с '5' для "./Dir_A".

Я собрал следующее, но он не совсем возвращает правильный ответ, и я не уверен, почему:

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<br />"; /* debugging */
                getFilecount( "$path/$file", $filecount, $total);  
            }  
        }  
    }  
    return $total;  
}  

Буду очень признателен за любую помощь.

Ответы [ 6 ]

18 голосов
/ 13 марта 2009

Это должно сработать:

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 голосов
/ 13 марта 2009

Используйте SPL, а затем проверьте, не появилась ли ошибка.

RecursiveDirectoryIterator

Пример использования:

<?php

$path = realpath('/etc');

$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
    echo "$name\n";
}

?>

Это печатает список всех файлов и каталогов в $ path (включая $ path ifself). Если вы хотите опустить каталоги, удалите часть RecursiveIteratorIterator :: SELF_FIRST.

Тогда просто используйте isDir ()

2 голосов
/ 25 января 2017

на основании ответа Эндрю ...

    $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!

вот так я могу считать (не перечисляя) тысячи и тысячи файлов. 680 642 файла меньше чем за 4,6 секунды;)

0 голосов
/ 03 апреля 2013

Паоло Бергантино был почти со своим кодом, но функция все равно будет считать файлы .DS_Store, так как он ошибся. Правильный код ниже

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 голосов
/ 13 марта 2009

Проверьте руководство PHP по функции glob(): http://php.net/glob

В комментариях есть примеры того, как сделать его рекурсивным.

0 голосов
/ 13 марта 2009

Почему вы передаете $ filecount? Значение [передано] не используется; единственное использование - "total + = $ filecount", и перед этим вы переопределяете $ filecount.

Вы пропускаете случай, когда функция встречает обычный (не-dir) файл.

Редактировать: я только что заметил вызов glob (). Это необязательно. В любом случае, ваша функция рекурсивно касается каждого файла во всем дереве каталогов. См. Ответ @Paolo Bergantino.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...