В PHP5 добавлен Iterator — набор готовых интерфейсов, помогающих перемещаться по иерархическим структурам данных и управлять ими. Это одна из самых интересных новых функций PHP5.
Эти итераторы значительно сокращают объем кода, необходимого для обработки дерева документов XML или набора файлов. В PHP5 используется большое количество итераторов, включая ArrayIterator, CachingIterator, LimitIterator, RecursiveIterator, SimpleXMLIterator и DirectoryIterator.
DirectoryIterator может быстро и эффективно обрабатывать файлы в каталоге. Проявив немного больше творчества в процессе кодирования, DirectoryIterator также можно использовать для рекурсивной обработки вложенных деревьев каталогов. Обе задачи можно решить, используя всего несколько строк кода, что является значительным улучшением по сравнению со «стандартным» подходом.
Обработка одноуровневого каталога Сначала мы начнем с простой задачи: обработки одноуровневого каталога. Введите (или скопируйте) следующий код (листинг A), изменив путь к каталогу в соответствии с локальной конфигурацией:
Листинг A
<?php$it = new DirectoryIterator("/tmp/mystuff");foreach($it as $file) {if ( !$it->isDot()) {echo $file . "n";}}?>Просмотрите вывод этого кода в браузере, вы увидите список файлов в указанном каталоге. Как это произошло? DirectoryIterator предоставляет заранее определенный интерфейс для повторного определения содержимого каталога; после выбора местоположения целевого каталога его можно рассматривать как стандартный массив PHP, где каждый элемент представляет файл в каталоге. Обратите внимание, что он использует метод isDot() для фильтрации каталогов «.» и «..» соответственно.
Обработка вложенных деревьев каталогов Рекурсивная обработка вложенных деревьев каталогов почти так же проста. В этом случае DirectoryIterator необходимо проверить каждый объект, который он встречает в одноуровневом каталоге, чтобы определить, является ли это файлом или каталогом. Если это каталог, перейдите на один уровень глубже, чтобы проверить содержимое следующего уровня. Это может показаться довольно сложным, и раньше обычно требовалось более 15 строк кода.
Однако в PHP5 вам понадобятся только два новых итератора: RecursiveIterator и RecursiveIteratorIterator, которые сочетают в себе все вышеперечисленные функции. См. список B:
Список B
<?php$it = new RecursiveDirectoryIterator("/tmp");foreach(new RecursiveIteratorIterator($it) as $file) {echo $file "n";}?>В это время введите В результате будут перечислены все файлы и каталоги в начальном каталоге. Излишне говорить, что этот рекурсивный встроенный интерфейс очень удобен, если вам нужно обработать все файлы на определенном уровне каталога — например, рекурсивно сжимать дерево каталогов или изменять права доступа группы/владельца для ряда вложенных файлов;
Реальное применение: печать дерева каталогов Печать графического дерева каталогов — распространенное применение рекурсии каталогов. Использовать Iterator для решения этой задачи очень просто, поскольку документация по классу Iterator содержит экземпляр класса, написанный специально для этого приложения. DirectoryTreeIterator (спасибо Маркусу Бургеру) предоставляет другие улучшения обсуждавшегося ранее RecursiveIteratorIterator, в частности, теги ASCII, представляющие глубину и положение в древовидной структуре.
Листинг C иллюстрирует использование DirectoryTreeIterator.
Листинг C
<?php$it = new DirectoryTreeIterator("/tmp/cookbook/");foreach($it as $path) {echo $path . "n";}?>Вот часть вывода, который вы видите:
| -ch01| |-example01.php| |-example01.php| |-example01.php... Чтобы лучше понять ценность этих DirectoryIterators, попробуйте написать три приложения, показанные в этом руководстве, с использованием стандартных функций файлов и каталогов.