Списки файлов в скриптах PHP: методы и практические применения
При работе с файловой системой на PHP часто возникает необходимость получить список файлов в виде массива. Это может потребоваться для последующей обработки, вывода на страницу или загрузки содержимого. В PHP существует несколько способов решения этой задачи, каждый из которых подходит для определенных сценариев.
Основные способы получения массива файлов
Как получить массив файлов по маске имени?
Функция glob() возвращает массив имен файлов или директорий, соответствующих заданному шаблону. Это наиболее часто используемый способ благодаря своей простоте и гибкости.
<?php
$files = glob('path/to/directory/*.txt');
print_r($files);
?>Htm php (html и php)
Результат: массив с именами всех текстовых файлов в указанной директории. Если файлов нет, возвращается пустой массив (начиная с PHP 5.4.0). Раньше мог быть false.
Типичная ошибка: отсутствие файлов в PHP до 5.4 приводило к false. Решение: проверять тип результата: if ($files !== false) { ... }.
Другая ошибка: неверный путь или права доступа. Функция возвращает false. Следует убедиться в существовании директории.
Цели использования: быстрое получение списка по шаблону (расширения, префикс), однократный перебор. Подходит для большинства простых задач.
Как получить полный список всех элементов в директории?
Функция scandir() возвращает массив, содержащий все файлы и папки, включая точки "." и "..".
<?php
$items = scandir('path/to/directory');
$filtered = array_diff($items, array('.', '..'));
print_r($filtered);
?>язык разработки php (php (язык разработки))
Пример удаляет служебные элементы. Если директория недоступна, возвращается false.
Проблема: необходимо фильтровать точки. Для больших директорий объем памяти может быть значительным.
Когда использовать: когда нужен полный список, включая папки, или при необходимости обработать все элементы без шаблона.
Как применить объектно-ориентированный подход для перебора файлов?
Класс DirectoryIterator предоставляет итератор для обхода содержимого папки.
<?php
$dir = new DirectoryIterator('path/to/directory');
$files = [];
foreach ($dir as $fileinfo) {
if ($fileinfo->isFile()) {
$files[] = $fileinfo->getFilename();
}
}
print_r($files);
?>
Custom index php (создание собственного index.php)
Метод isFile() отсеивает папки. Результат: массив только файлов.
Особенность: итератор не загружает все данные сразу, экономит память. Однако обработка через foreach может быть медленнее на очень больших папках.
Цели: когда требуется гибкая фильтрация или обработка каждого файла с использованием методов объекта SplFileInfo.
Как получить все файлы из поддиректорий в виде одного массива?
Для рекурсивного обхода используется RecursiveDirectoryIterator в сочетании с RecursiveIteratorIterator.
<?php
$rdi = new RecursiveDirectoryIterator('path/to/directory');
$it = new RecursiveIteratorIterator($rdi);
$files = [];
foreach ($it as $fileinfo) {
if ($fileinfo->isFile()) {
$files[] = $fileinfo->getPathname();
}
}
print_r($files);
?>Https page php (страница php через https)
Результат: массив полных путей ко всем файлам рекурсивно.
Проблема: при большом количестве файлов может исчерпаться память. Также могут быть ошибки доступа к подпапкам. Рекомендуется использовать ограничение глубины через RecursiveIteratorIterator::setMaxDepth().
Когда использовать: задачи, требующие обхода всего дерева, например, поиск всех изображений в проекте.
Как загрузить содержимое всех файлов директории в массив?
Комбинация glob() и array_map() позволяет получить массив содержимого всех файлов.
<?php
$files = glob('path/to/directory/*.txt');
$contents = array_map(function($file) {
return file_get_contents($file);
}, $files);
print_r($contents);
?>простой php (простые примеры php)
Каждый элемент массива содержит текст файла. При ошибке чтения file_get_contents вернет false, что требует дополнительной проверки.
Ошибка: если файл недоступен или битый, file_get_contents возвращает false. Решение: обернуть в try-catch или использовать file() с проверкой.
Цель: быстрая загрузка содержимого для последующей обработки, например, объединения или анализа.
Как отфильтровать файлы по расширению после scandir?
Используется array_filter() с обратным вызовом, проверяющим расширение.
<?php
$items = scandir('path/to/directory');
$files = array_filter($items, function($item) {
$ext = pathinfo($item, PATHINFO_EXTENSION);
return $ext === 'php';
});
print_r(array_values($files));
?>
Фильтр оставляет только файлы с расширением .php. Обратите внимание, что папки тоже попадают в массив, если их имя содержит точку. Лучше дополнительно проверять is_file.
Проблема: папки с точкой могут быть ошибочно включены. Решение: добавить проверку is_file() внутри callback.
Пример 1: Рекурсивное получение файлов с определённым расширением и ограничением глубины
<?php
$path = '/var/log';
$rdi = new RecursiveDirectoryIterator($path);
$it = new RecursiveIteratorIterator($rdi, RecursiveIteratorIterator::SELF_FIRST);
$it->setMaxDepth(2); // ограничение глубины
$logFiles = [];
foreach ($it as $fileinfo) {
if ($fileinfo->isFile() && $fileinfo->getExtension() === 'log') {
$logFiles[] = $fileinfo->getPathname();
}
}
print_r($logFiles);
?>
Array
(
[0] => /var/log/syslog
[1] => /var/log/auth.log
[2] => /var/log/kern.log
[3] => /var/log/dmesg
)
В примере ищутся файлы с расширением .log на глубине не более двух папок. Используется setMaxDepth() для контроля.
Пример 2: Использование GLOB_BRACE для поиска файлов нескольких расширений
<?php
$files = glob('path/to/documents/{*.pdf,*.doc,*.txt}', GLOB_BRACE);
print_r($files);
?>
Array
(
[0] => path/to/documents/report.pdf
[1] => path/to/documents/notes.txt
[2] => path/to/documents/letter.doc
)
Флаг GLOB_BRACE позволяет задать несколько альтернативных шаблонов. Удобно для выборки разных типов файлов.
Пример 3: Загрузка содержимого файлов с обработкой ошибок
<?php
$files = glob('data/*.csv');
$contents = [];
foreach ($files as $file) {
$content = @file_get_contents($file); // подавление предупреждения
if ($content === false) {
$contents[$file] = 'Ошибка чтения';
} else {
$contents[$file] = $content;
}
}
print_r($contents);
?>
Array
(
[data/sales.csv] => date,amount,product
2024-01-01,150,Widget
...
[data/broken.csv] => Ошибка чтения
)
Здесь каждый файл читается отдельно, ошибки заносятся в ассоциативный массив. Оператор @ подавляет предупреждение, но лучше использовать проверку is_readable() или try-catch.
Пример 4: Создание ассоциативного массива (имя файла => размер) через DirectoryIterator
<?php
$dir = new DirectoryIterator('/path/to/images');
$fileSizes = [];
foreach ($dir as $fileinfo) {
if ($fileinfo->isFile()) {
$fileSizes[$fileinfo->getFilename()] = $fileinfo->getSize();
}
}
print_r($fileSizes);
?>
Array
(
[photo1.jpg] => 204800
[photo2.png] => 512000
[photo3.gif] => 102400
)
Метод getSize() возвращает размер в байтах. Подобным образом можно получить дату модификации, права доступа и другие атрибуты.