Php директория файла. Получение списка файлов и директорий с помощью PHP. Использование итераторов SPL

В данном уроке мы разберемся с типовой задачей, которая возникает во время работы над проектом 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(), которая позволяет выполнять поиск пути с помощью шаблонов. Функция имеет два параметра:

  • $pattern (обязательный): шаблон поиска
  • $flags (опциональный): один или несколько флагов, описание которых можно найти в документации

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

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

Array (0 => "article.txt", 1 => "text.txt")

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

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

Array (0 => "test.dat", 1 => "text.txt")

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

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

Array (0 => "manager")

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

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

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

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

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

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

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

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

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

Array (0 => "article.txt", 1 => "master.dat", 2 => "script.php", 3 => "test.dat", 4 => "text.txt")

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

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

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

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

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

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

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

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

  • $path (обязательный): путь к пункту файловой системы, над которым совершаются операции
  • $flags (опциональный): один или несколько флагов, перечисленных в документации

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

FilesystemIterator

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

getFilename(), "te") === 0) { $filelist = $entry->getFilename(); } }

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

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

getFilename(); }

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

Array (0 => "script.php", 1 => "test.dat")

RecursiveDirectoryIterator

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

getChildren(), "/t\.(php|dat)$/"); $filelist = array(); foreach($filter as $entry) { $filelist = $entry->getFilename(); }

GlobIterator

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

getFilename(); }

Заключение

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

  • Функция glob() является встроенным решением, но она недостаточно гибкая.
  • Решение на основе opendir() , readdir() , и closedir() более сложное и требует дополнительной фильтрации, но оно более гибкое.
  • Функция scandir() требует дополнительной фильтрации, но работает без обработки дескриптора.
  • Если вы используете подход ООП, то следует применять библиотеку SPL. Дополнительно вы можете расширить классы своим функционалом.
  • Итератор GlobIterator имеет функцию предварительной фильтрации, а другие используют RegexIterator .

Работа с файлами

Необходимость в операциях с файлами встает перед программистом очень часто. Если ваши скрипты не используют баз данных, то файлы остаются единственными приемлемыми хранителями информации для скрипта. Применение файлов как хранилищ информации выполнения скрипта позволяет использовать их в самых разнообразных ситуациях. Практически все скрипты-счетчики чего-либо написаны на основании работы с файлами. Также возможно привести кучу других примеров, но пора переходить непосредственно от слов к делу.

Сразу хочу сказать, что работа с файлом должна быть санкционирована. По умолчанию PHP не допускает работу с файлом в целях безопасности. Чтобы снять этот запрет в FTP-менеджере CuteFTP в свойствах файла выставьте все галочки, в других менеджерах должно быть что-то подобное.

file_exists

Прежде, чем производить операции с файлом, часто необходимо убедиться, что указанный файл вообще существует. Этим и занимается функция file_exists . Эта функция может возвращать только два значения, как вы сами понимаете, TRUE (если указанный файл существует) и FALSE . Обычно использование данной функции выглядит так:

Заметьте, что функция действует только на локальных файлах, то есть если вы возжелаете проверить, обзавелся ли Яндекс файлом robot.txt, то ваши усилия будут тщетны. Но зато возможно проверить любой файл, лежащий на локальном сервере независимо от директории его расположения.

Вот некоторые правила описания пути к файлу.

filesize

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

file

Эта функция уже непосредственно работает с файлом. Она возвращает содержимое указанного файла, причем делает она это в виде массива, где каждый его элемент является строкой файла. Функция полезна, когда в одном файле необходимо сохранить несколько разных значений, которые не должны пересекаться. Тогда каждое значение сохраняется на отдельной строке и читается функцией file , которая возвращает массив, вследствие чего обращение к заданной переменной происходит с помощью чтения значения элемента массива с индексом, соответствующим строке в файле.

Кроме того, возможно воссоединение всех элементов возвращенного массива в одну переменную. Это делается с помощью функции работы с массивами implode .

fopen

Если предыдущая функция самодостаточна и в общем не связана с другими функциями, то последующие функции работы с файлами работают в связке с fopen . Эта функция открывает указанный файл и возвращает идентификатор соединения с файлом, который используется в служебных целях. С содержимым файла эта функция никаким образом не связывается.

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

    "r"
    Файл открывается только для чтения его содержимого.

    "r+"
    Открытие файла как для чтения, так и для записи.

    "w"
    Файл открывается с целью записи.

    "w+"
    Открыть файл для чтения и записи.

    "a"
    Файл открывается для записи в конец файла (дозаписи).

    "a+"
    Открывается для дозаписи и чтения.

fgets

Функция чтения файла, открытого функцией fopen . Но в отличие от file , эта функция за каждый раз своего выполнения возвращает только одну строку файла, при этом она перемещает внутренний указатель файла на следующую строку, которую она прочитает при следующем обращении к функции. Поэтому, если вам необходимо прочитать файл целиком, необходимо использовать эту функцию в цикле.

Заметьте, что функция fgets использует дополнительный параметр length , который указывает максимальную длину строки файла для чтения. Если объем строки превышает это число, то функция возратит ее в "урезанном" виде объемом в число length байт. По умолчанию этот параметр установлен в 1024 байт, или в один килобайт. Тем более обратите внимание на этот параметр, если вы используете файлы больших размеров, так как при чтении таких файлов может переполниться буфер выполнения PHP (его объем указывается в файле конфигурации), что приведет к зависанию.

Обратите внимание, что в качестве указания файла для чтения необходимо указывать не имя файла, а идентификатор соединения с файлом, возвращенный функцией fopen (в нашем примере это значение переменной $file).

fputs

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

fclose

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

Для иллюстрации связки вышеуказанных функций приведем пример создания простого счетчика посещений.

$file = fopen("counter.txt", "r");
$c = fgets ($file, 150);
fclose ($file);
$c++;
$file = fopen("counter.txt", "w");
fputs ($file, $c);
fclose ($file);
echo $c;
?>

Работа с директориями

Тесно связаны с действиями над файлами операции с директориями. Алгоритм работы с ними схож с операциями над файлами: сначала директорию необходимо открыть, выполнить какие-либо действия и, наконец, закрыть ее.

opendir

Эта функция открывает указанную директорию и возвращает служебный идентификатор соединения с директорией. Пути к директории следует указывать следующим образом:

Точка означает открытие текущей директории

. /files/

Открытие папки files , находящейся в текущей директории

Открытие папки на уровень выше текущей

readdir

Функция читает директорию, открытую opendir . За каждый проход она возвращает имя файла или папки, лежащих в указанной директории, и перемещает внутренний указатель на следующий объект директории. Так что для прочтения всей директории ее необходимо использовать в цикле.

Также необходимо заметить, что эта функция возвращает служебные объекты папки . и .. , которые можно отсекать при выводе оператором IF .

closedir

Закрываем директорию, указывая в качестве аргумента идентификатор соединения с папкой.

Иногда использование функций работы с директориями очень облегчают жизнь. Например, в разделе Функции вы можете видеть список функций в алфавитном порядке. Представляете, сколько времени нужно было бы потратить, чтобы вручную написать весь этот список с ссылками, да еще и в алфавитном порядке. И вот как раз здесь мне помогли функции работы с директорией. Каждая функция была помещена в отдельный файл с именем, соответствующим названию функции, без каких-либо расширений.

Так что, при каждом заходе на страницу вы получаете только что сгенерированный список функций.

На этом все. Встретимся на следующем уроке.

Reg.ru: домены и хостинг

Крупнейший регистратор и хостинг-провайдер в России.

Более 2 миллионов доменных имен на обслуживании.

Продвижение, почта для домена, решения для бизнеса.

Более 700 тыс. клиентов по всему миру уже сделали свой выбор.

*Наведите курсор мыши для приостановки прокрутки.

Назад Вперед

Получение списка папок с помощью PHP

Список каталогов средствами PHP, или листинг директорий

Листингом директорий мы будем называть запрос общего вида, формирующий список всех, либо некоторых файлов и каталогов родительской директории - процесс похожий на работу индексной страницы, обеспечиваемой большинством веб-серверов, но с бо льшим контролем над контентом и форматированием оного же.

Ещё одно преимущество данного скрипта - возможность выполнять определённые действия с файлами, используя PHP. В любом случае, первый шаг, который нам нужно сделать - это запрос к файловой системе - вернуть список файлов и каталогов.

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

Замечание: в PHP5 есть функция scandir , которая "возвращает список файлов и каталогов, внутри директории, по заданному пути", однако она не выводит какую-либо дополнительную информацию о находящихся внутри директории файлах.

Листинг одной директории

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

read())) { // пропустить скрытые файлы if($entry == ".") continue; if(is_dir("$dir$entry")) { $retval = array("name" => "$dir$entry/", "size" => 0, "lastmod" => filemtime("$dir$entry")); } elseif(is_readable("$dir$entry")) { $retval = array("name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); } } $d->close(); return $retval; } ?>

Вы можете использовать эту функцию как ниже:

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

Пример 1:

",print_r($dirlist),""; /* пример вывода Array ( => Array ( => images/background0.jpg => image/jpeg => 86920 => 1077461701) => ...) */ ?>

Пример 2:

",print_r($dirlist),""; /* пример вывода Array ( => Array ( => ./images/background0.jpg => image/jpeg => 86920 => 1077461701) => ...) */ ?>

Вывод списка файлов через HTML

Чтобы получить результаты вывода на странице в HTML, мы прокрутим возвращаемый массив через цикл

\n"; echo "NameTypeSizeLast Mod.\n"; foreach($dirlist as $file) { echo "\n"; echo "{$file["name"]}\n"; echo "{$file["type"]}\n"; echo "{$file["size"]}\n"; echo "\n"; echo "\n"; } echo "\n\n"; ?>

Этот код довольно просто модифицировать, например:

  • - вывести результаты листинга списком вместо таблицы;
  • - сделать названия файлов активными ссылками;
  • - заменить имена иконками на основании того, какой тип у файла;
  • и т.д.

Например, для вывода только PNG-файлов, добавьте простое условие в цикл вывода:

\n"; echo "NameTypeSizeLast Mod.\n"; foreach($dirlist as $file) { //проверка на принадлежность файла к PNG if(!preg_match("/\.png$/", $file["name"])) continue; echo "\n"; echo "{$file["name"]}\n"; echo "{$file["type"]}\n"; echo "{$file["size"]}\n"; echo "",date("r", $file["lastmod"]),"\n"; echo "\n"; } echo "\n\n"; ?>

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

Если вы, например, хотите отобразить миниатюру, ссылкой на картинку большего размера, или даже видео, просто задайте этим 2-м файлам одинаковые имена и в скрипте выше используйте str_replace или похожую функцию, чтобы модифицировать содержимое ссылок.

Рекурсивный листинг директории

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

read())) { // пропустить скрытые файлы if($entry == ".") continue; if(is_dir("$dir$entry")) { $retval = array("name" => "$dir$entry/", "size" => 0, "lastmod" => filemtime("$dir$entry")); if($recurse && is_readable("$dir$entry/")) { $retval = array_merge($retval, getFileList("$dir$entry/", true)); } } elseif(is_readable("$dir$entry")) { $retval = array("name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); } } $d->close(); return $retval; } ?>

Чтобы новый функционал заработал, вам нужно ввести значение true (или 1) в качестве второго параметра.

Перед рекурсингом скрипта проверьте, являются ли поддиректории читабельными а также ознакомьтесь с последним пунктом данного урока, дабы избежать ошибок доступа.

Как и раньше, возвращаемая величина - это массив, ассоциативный массивов. Фактически, единственное дополнение - это ещё одна дополнительная опция для рекурсивного листинга.

Ограничение глубины рекурсии

Этот финальный пример добавляет ещё одно свойство - способность к определению, как "глубоко" должна проходить рекурсия. Предыдущий код будет продолжать исследовать вложенные директории, до тех пор пока они не закончатся. Этот скрипт поможет установить ограничение, по количеству уровней вложенных директорий.

read())) { // пропустить скрытые файлы if($entry == ".") continue; if(is_dir("$dir$entry")) { $retval = array("name" => "$dir$entry/", "size" => 0, "lastmod" => filemtime("$dir$entry")); if($recurse && is_readable("$dir$entry/")) { if($depth === false) { $retval = array_merge($retval, getFileList("$dir$entry/", true)); } elseif($depth > 0) { $retval = array_merge($retval, getFileList("$dir$entry/", true, $depth-1)); } } } elseif(is_readable("$dir$entry")) { $retval = array("name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry")); } } $d->close(); return $retval; } ?>

Как и раньше, мы добавили всего 1 новый параметр и пару строк кода. Если значение по умолчанию, отвечающее за глубину рекурсинга, не задано, то оно устанавливается в false . Это позволяет нам быть уверенными в том, что предыдущие особенности остаются и последующий код не "поломается" при изменении функции.

scandir — Получает список файлов и каталогов, расположенных по указанному пути

Описание

Array scandir (string $directory [, int $sorting_order = SCANDIR_SORT_ASCENDING [, resource $context ]])

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

Список параметров

Сканируемый каталог.

Sorting_order

По умолчанию, сортировка производится в алфавитном порядке по возрастанию. Если необязательный параметр sorting_order установлен в значение SCANDIR_SORT_DESCENDING , сортировка производится в алфавитном порядке по убыванию. Если же он установлен в значение SCANDIR_SORT_NONE , то сортировка не производится.

Context

За описанием параметра context обратитесь к разделу "Потоки " данного руководства.

Возвращаемые значения

Возвращает array имен файлов в случае успеха или FALSE в случае ошибки. Если directory не является каталогом, возвращается FALSE и генерируется сообщение об ошибке уровня E_WARNING .

Список изменений

Примеры

Пример #1 Простой пример использования функции scandir()

$dir = "/tmp" ;
$files1 = scandir ($dir );
$files2 = scandir ($dir , 1 );

Print_r ($files1 );
print_r ($files2 );
?>

Результатом выполнения данного примера будет что-то подобное:

Array ( => . => .. => bar.php => foo.txt => somedir) Array ( => somedir => foo.txt => bar.php => .. => .)

Пример #2 Альтернативный вариант функции scandir() для PHP 4

$dir = "/tmp" ;
$dh = opendir ($dir );
while (false !== ($filename = readdir ($dh ))) {
$files = $filename ;
}

Sort ($files );

Print_r ($files );

Rsort ($files );

Print_r ($files );

В данном уроке мы разберемся с типовой задачей, которая возникает во время работы над проектом 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(), которая позволяет выполнять поиск пути с помощью шаблонов. Функция имеет два параметра:

  • $pattern (обязательный): шаблон поиска
  • $flags (опциональный): один или несколько флагов, описание которых можно найти в документации

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

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

Array (0 => "article.txt", 1 => "text.txt")

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

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

Array (0 => "test.dat", 1 => "text.txt")

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

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

Array (0 => "manager")

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

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

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

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

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

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

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

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

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

Array (0 => "article.txt", 1 => "master.dat", 2 => "script.php", 3 => "test.dat", 4 => "text.txt")

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

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

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

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

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

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

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

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

  • $path (обязательный): путь к пункту файловой системы, над которым совершаются операции
  • $flags (опциональный): один или несколько флагов, перечисленных в документации

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

FilesystemIterator

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

getFilename(), "te") === 0) { $filelist = $entry->getFilename(); } }

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

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

getFilename(); }

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

Array (0 => "script.php", 1 => "test.dat")

RecursiveDirectoryIterator

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

getChildren(), "/t\.(php|dat)$/"); $filelist = array(); foreach($filter as $entry) { $filelist = $entry->getFilename(); }

GlobIterator

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

getFilename(); }

Заключение

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

  • Функция glob() является встроенным решением, но она недостаточно гибкая.
  • Решение на основе opendir() , readdir() , и closedir() более сложное и требует дополнительной фильтрации, но оно более гибкое.
  • Функция scandir() требует дополнительной фильтрации, но работает без обработки дескриптора.
  • Если вы используете подход ООП, то следует применять библиотеку SPL. Дополнительно вы можете расширить классы своим функционалом.
  • Итератор GlobIterator имеет функцию предварительной фильтрации, а другие используют RegexIterator .
Loading...Loading...