Сколько файлов в папке? PHP-решения и практические советы
Основные способы подсчёта файлов
В PHP существует несколько вариантов определить количество файлов в папке. Ниже рассмотрены основные подходы с примерами кода и указанием особенностей.
Как эффективно подсчитать файлы в одной директории?
Наиболее производительный способ - использовать класс FilesystemIterator. Он не загружает сразу все имена в память, а итерирует по элементам директории. Пример:
$dir = '/path/to/dir';
$iterator = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
$count = iterator_count($iterator);
echo $count;Include system php (включение системного файла)
Проблема: при очень большом количестве файлов (сотни тысяч) iterator_count всё равно может потреблять много ресурсов. Решение: если требуется только количество, можно использовать прямой системный вызов exec('ls -1 | wc -l'), но это не кроссплатформенно. Для PHP предпочтительнее FilesystemIterator, так как он оптимизирован для работы с файловой системой.
Как сосчитать файлы без учёта точек с помощью scandir?
$files = scandir($dir);
$count = count($files) - 2; // исключаем . и ..
echo $count;Ru reading php line (чтение строки из файла php)
Ошибка: если в папке нет файлов, scandir вернёт массив ['.', '..'], тогда count($files) - 2 даст 0, что верно. Но если папка недоступна, возникнет Warning. Нужна проверка is_dir($dir).
Как подсчитать файлы по маске с помощью glob?
$files = glob($dir . '/*.txt');
echo count($files);Php file get html (получение html файла через php)
Проблема: glob не ищет рекурсивно. Для вложенных папок нужно использовать ** (требуется PHP >= 5.5.0 и флаг GLOB_BRACE). Также glob возвращает полные пути, что увеличивает потребление памяти.
Как рекурсивно подсчитать файлы во всех подпапках?
$iterator = new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator);
echo iterator_count($files);Php файловая система (работа с файловой системой в php)
Ошибка: RecursiveIteratorIterator перебирает также каталоги, если не задать фильтр. Чтобы считать только файлы, нужно проверить $file->isFile(). Альтернатива - использовать AppendIterator или фильтр RegexIterator.
Как подсчитать файлы с использованием DirectoryIterator?
$count = 0;
foreach (new DirectoryIterator($dir) as $file) {
if (!$file->isDot() && $file->isFile()) $count++;
}
echo $count;Проблема: DirectoryIterator медленнее FilesystemIterator из-за дополнительных вызовов методов. Но он даёт больше контроля (проверка типа, размера, времени).
Расширенные примеры подсчёта файлов
Рекурсивный подсчёт с отбором только файлов
function countFilesRecursive($dir) {
$iterator = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$fileCount = 0;
foreach (new RecursiveIteratorIterator($iterator) as $file) {
if ($file->isFile()) $fileCount++;
}
return $fileCount;
}
$total = countFilesRecursive('/path/to/start');
echo "Всего файлов: $total";Всего файлов: 145
Этот подход потребляет память пропорционально глубине вложенности, но не хранит список всех файлов. Для больших деревьев можно ограничить глубину через RecursiveIteratorIterator::setMaxDepth().
Подсчёт файлов определённого расширения с рекурсией
$filter = new RegexIterator(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
),
'/\.php$/'
);
echo iterator_count($filter);23
Здесь RegexIterator фильтрует только те файлы, полный путь которых соответствует регулярному выражению. Быстро и удобно.
Подсчёт числа файлов с игнорированием скрытых (начинающихся с точки)
$count = 0;
foreach (new FilesystemIterator($dir) as $file) {
$name = $file->getFilename();
if ($name[0] !== '.' && $file->isFile()) $count++;
}
echo $count;88
Обратите внимание: FilesystemIterator::SKIP_DOTS исключает только . и .., но не скрытые файлы (.htaccess и т.п.). Если нужно игнорировать всё, что начинается с точки, используйте проверку.
Подсчёт файлов с использованием scandir и фильтрации типов
$files = array_filter(scandir($dir), function($item) use ($dir) {
return is_file($dir . '/' . $item);
});
echo count($files);10
Этот метод загружает весь список в память, но позволяет применить любую пользовательскую логику фильтрации.
Подсчёт с обработкой ошибок доступа
function safeCountFiles($dir) {
try {
$iterator = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
return iterator_count($iterator);
} catch (UnexpectedValueException $e) {
// ошибка доступа или папка не существует
return 0;
}
}
echo safeCountFiles('/root/protected');0
Такой подход позволяет избежать Warning и обрабатывать исключения без остановки скрипта.