PHP: список файлов и директорий

В данном уроке мы разберемся с типовой задачей, которая возникает во время работы над проектом PHP: получение списка файлов и директорий. Обсудим несколько базовых и более изощренных подходов, с перечисление плюсов и минусов каждого. Первые три решения будут использовать типовые функции PHP, а затем представим  более надежное с применением итераторов SPL.

Для предметного обсуждения решения и демонстраций предположим, что структура директорий имеет следующий вид:

—manager | —user | —document.txt | —data.dat | —style.css |—article.txt |—master.dat |—script.php |—test.dat |—text.txt

 

Базовые решения

Первый набор решений основан на использовании функции glob(), комбинации функций opendir(), readdir() и closedir(), и также функции scandir().

 

Использование glob()

Первое решение базируется на использовании функции glob(), которая позволяет выполнять поиск пути с помощью шаблонов. Функция имеет два параметра:

Рассмотрим примеры. Для поиска в директории всех файлов и директорий, имена которых заканчиваются на .txt, следует использовать код:

<?php $filelist = glob(«*.txt»);

Если вывести переменную $filelist, то получим:

array ( 0 => ‘article.txt’, 1 => ‘text.txt’ )

Если нужен список файлов и директорий, имена которых начинаются на “te”, то код будет выглядеть так:

<?php $filelist = glob(«te*»);

А вывод имеет вид:

array ( 0 => ‘test.dat’, 1 => ‘text.txt’ )

А для получения списка только директорий с именами, содержащих “ma”, используем код:

<?php $filelist = glob(«*ma*», GLOB_ONLYDIR);

Последний пример выведет:

Обратите внимание, что в последнем примере использован флаг GLOB_ONLYDIR в качестве второго параметра функции. Поэтому файл master.dat исключен из списка. Хотя функция glob() очень проста в использовании, иногда она недостаточно гибкая. Например, нет флага для получения только файлов (без директорий), которые соответствуют шаблону.

 

Используем opendir(), readdir(), и  closedir().

Второй подход к получению списка файлов и директорий, который мы обсудим, заключается в использовании функций  opendir(), readdir(), и closedir().

Функция  opendir() открывает директорию и возвращает дескриптор соединения. Как только дескриптор получен, можно использовать функцию readdir(). С каждым обращением данная функция выдает имя следующего файла или директории внутри открытого каталога. Если все имена уже были перечислены, функция возвращает false. Для закрытия дескриптора используется функция closedir().

В отличие от использования функции glob(), данный подход сложнее, так как у вас нет параметров, которые помогают фильтровать список возвращаемых имен файлов и директорий. Вы должны выполнить фильтрацию самостоятельно, чтобы получить нужный результат.

Ниже приведенный пример возвращает список имен файлов и директорий начинающихся на “te”:

<?php $filelist = array(); if ($handle = opendir(«.»)) { while ($entry = readdir($handle)) { if (strpos($entry, «te») === 0) { $filelist[] = $entry; } } closedir($handle); }

При выполнении выше приведенного кода, переменная $entry будет содержать такие включения, как  “.” и “..”. Это две виртуальные директории, которые имеются в каждом каталоге файловой системы. Они представляют текущий каталог и родительский каталог соответственно.

Второй пример выводит только файлы, содержащиеся в заданном каталоге.

<?php $filelist = array(); if ($handle = opendir(«.»)) { while ($entry = readdir($handle)) { if (is_file($entry)) { $filelist[] = $entry; } } closedir($handle); }

Пример выдаст следующее:

array ( 0 => ‘article.txt’, 1 => ‘master.dat’, 2 => ‘script.php’, 3 => ‘test.dat’, 4 => ‘text.txt’ )

 

Использование scandir()

В завершение представим функцию scandir(). Она имеет только один обязательный параметр: путь для чтения.  Функция возвращает массив фалов и директорий, расположенных по указанному пути. Для получения списка файлов и директорий по определенному критерию нужно выполнить дополнительную фильтрацию. С другой стороны, решение получается более кратким и не требует управления дескрипторами.

Данный пример показывает, как получить список фалов и каталогов, имена которых начинаются на “te”:

<?php $entries = scandir(«.»); $filelist = array(); foreach($entries as $entry) { if (strpos($entry, «te») === 0) { $filelist[] = $entry; } }

 

 

Воспользуемся итераторами SPL

Теперь рассмотрим использование итераторов SPL. Но прежде, чем приступить к решению нашей задачи, проведем введение в библиотеку SPL и итераторы. Библиотека SPL предоставляет серию классов для объектно ориентированных структур данных, итераторов, дескрипторов фалов и прочее.

Одно из преимуществ итераторов заключается в том, что они являются классами и их можно расширить для удовлетворения собственных нужд. Другой плюс состоит в том, что итераторы имеют собственные методы, которые являются полезными при решении множества типовых задач и располагаются в одном месте. Посмотрите на пример использования FilesystemIterator в сравнении с readdir(). Оба метода применяют цикл, но в случае readdir() вы обрабатываете только строку, а  FilesystemIterator работает с объектом, который может содержать дополнительную информацию о файле или директории (размер, владелец, права доступа и так далее).

Конечно, PHP представляет возможность для получения такой информации с помощью функций,например filesize() и fileowner(). Но PHP5 основан на использовании концепции ООП. Поэтому лучше использовать современные методы работы с языком программирования. На нашем сайте есть уроки, посвященные работе с итераторами.

Как уже сообщалось во водной части урока, мы рассмотрим использование  FilesystemIterator, RecursiveDirectoryIterator и GlobIterator. Первый наследуется от DirectoryIterator, а остальные от FilesystemIterator. Они все имеют один и тот же конструктор, который принимает два параметра:

Реальное различие в данных итераторах заключается в их использовании для навигации по заданному пути.

 

FilesystemIterator

 

Использовать FilesystemIterator очень просто. Рассмотрим в действии. Представляем два примера. Первый показывает поиск всех файлов и каталогов, имена которых начинаются на “te”. Второй пример использует другой итератор RegexIterator для поиска всех фалов и каталогов, имена которых заканчиваются на “t.dat” или “t.php”. Итератор RegexIterator используется для фильтрации результата на основе регулярных выражений.

<?php $iterator = new FilesystemIterator(«.»); $filelist = array(); foreach($iterator as $entry) { if (strpos($entry->getFilename(), «te») === 0) { $filelist[] = $entry->getFilename(); } }

Выше приведенный код выдаст результат, аналогичный предыдущим примерам.

Второй пример с применением RegexIterator:

<?php $iterator = new FilesystemIterator(«.»); $filter = new RegexIterator($iterator, ‘/t.(php|dat)$/’); $filelist = array(); foreach($filter as $entry) { $filelist[] = $entry->getFilename(); }

Он будет выводить:

array ( 0 => ‘script.php’, 1 => ‘test.dat’ )

 

RecursiveDirectoryIterator

Итератор RecursiveDirectoryIterator обеспечивает интерфейс для рекурсивного прохода по директориям файловой системы. Он имеет несколько полезных методов, таких как getChildren() и hasChildren(), которые возвращают итератор для текущего места, если это директория, и проверяют, является ли текущая точка входа директорией. Следующий пример демонстрирует использование RecursiveDirectoryIterator и getChildren(). Результат будет такой же, как и в предыдущих примерах.

<?php $iterator = new RecursiveDirectoryIterator(‘.’); $filter = new RegexIterator($iterator->getChildren(), ‘/t.(php|dat)$/’); $filelist = array(); foreach($filter as $entry) { $filelist[] = $entry->getFilename(); }

 

GlobIterator

Итератор GlobIterator выполняет проход по файловой системе также, как и функция glob(). Первый параметр может включать шаблон для имени. Пример демонстрирует использование GlobIterator с тем же результатом, что и ранее.

<?php $iterator = new GlobIterator(«te*»); $filelist = array(); foreach($iterator as $entry) { $filelist[] = $entry->getFilename(); }

 

Заключение

В данном уроке демонстрируется использование различных подходов для достижение одинаковой цели: получение списка файлов и директорий. Следует запомнить следующие ключевые моменты:

Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/fWQpdbbOVDY/lessons.php

Источник: lred.ru

Оцените статью
новости для мужчин