Простой вопрос для newb и моего 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; / * отладка * / echo "$ total"; / * отладка * / echo "$ path / $ file
"; / * отладка * / getFilecount («$ path / $ file», $ filecount, $ total); } } } return $ total; }
Я бы очень признателен за любую помощь.
Это должно сделать трюк:
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; }
Используйте 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 ()
Почему вы передаете $ filecount? Значение [прошедшего] не используется; единственное использование – «$ total + = $ filecount», и перед этим вы переопределяете $ filecount.
Вам не хватает случая, когда функция встречает обычный (не-dir) файл.
Изменить: я просто заметил вызов glob (). Это необязательно. Во всяком случае, ваша функция рекурсивно затрагивает каждый файл во всем дереве каталогов. См. Ответ @Paolo Bergantino.
Паоло Бергантино был почти с его кодом, но функция все равно будет считать файлы .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; }
основанный на ответе Андрея …
$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 секунды;)
Проверьте руководство PHP по функции glob()
: http://php.net/glob
В комментариях есть примеры того, как сделать это рекурсивным.