DirectoryIterator — класс в PHP, для работы с файловой системой


Содержание материала:

PHP DirectoryIterator

Сейчас очень много работаю с SPL классами в PHP. Честно говоря, работать с ними не всегда удобно. Сегодня наткнулся на проблему с указателями в DirectoryIterator. Ее суть хорошо отражает следующий код.

Проблема состоит в том, что при выполнении foreach у нас в элементе $item находится указатель на указатель (вот такой вот каламбур) текущего элемента в DirectoryIterator. Получить этот указатель можно с помощью функции $dirTree->current(). Таким образом, при изменении этого самого внутреннего указателя изменяется и результат выполнения команды getFilename. А так как после выполнения Foreach указатель смотрит на несуществующий (null) элемент итератора, то getFilename возвращает пустое значение.

Пока я ничего лучше не придумал, чем копировать $item с помощью метода clone:

Решение ужасное, поэтому если кто-то подскажет действительно красивый способ выдернуть из DirectoryIterator набор директорий в виде массива директорий, то буду очень признателен.

OpenSource в заметках

Когда я впервые наткнулся на термин «итерация» и увидел огромное количество классов, связанных с этим термином, я опешил. Мне показалось, что всё это слишком сложно, чтобы разобраться. Но совсем скоро я понял, что «итерация» — это всего лишь умное словечко, чтобы описать то, что программисты используют каждый день.

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

Это первая часть и двухсерийной статьи. В ней я расскажу вам об итерации и о преимуществах использования некоторых классов Standard PHP Library (SPL). В SPL присутствует огромное количество итераторов и их использование во многих случаях может сделать ваш код эффективнее и читабельнее.

Где и когда использовать итераторы SPL

Как вы скоро увидите, работа с итераторами примерно напоминает работу с массивами и отчасти по этой причине многие люди задаются вопросом: зачем вообще нужны эти итераторы, если есть массивы? Реальную выгоду от использования итераторов можно получить в случаях, когда нужно итерировать большие объёмы данных, а также данные, которые по своей структуре сложнее обычного массива.

Цикл foreach создаёт копию полученного массива. Если вы имеете дело с большими объёмами данных, такой подход не годится по очевидной причине: снижение производительности. Итератор SPL работает по другому: он обрабатывает один элемент итерируемого списка за раз, делая это куда более эффективно, нежели foreach .

При создании поставщиков данных (data providers) итераторы помогают сделать их более эффективными, предлагаю возможности ленивой загрузки (lazy loading). «Ленивая загрузка» означает то, что фактическое получение данных из источника выполняет только тогда, когда эти данные нужны. Помимо прочего, вы получаете возможность трансформации данных перед тем, как отдавать их клиенту объекта.

Однако ответ на вопрос «использовать итераторы или нет» остаётся полностью результатом вашего выбора. Итераторы имею массу полезных свойств, но в некоторых случаях (в частности, с маленькими объёмами данных) затраты на их применение будут неоправданными. В любом случае, выбор остаётся за вами. Всегда старайтесь рассмотреть максимальное количество факторов, прежде чем принимать решение.

Итерация массивов

Первый итератор, который я вам хочу представить — это ArrayIterator . Его конструктор принимает массив в качестве параметра, а сам объект предоставляет методы для выполнения итерационных операций. Вот пример работы с ArrayIterator :

В результате получим следующий вывод:

Вообще. обычно вы будете использовать ArrayObject в таких случаях, вместо непосредственного использовани ArrayIterator , поскольку первый позволяет работать с объектом как с массивом в определённых контекстах. ArrayObject создаёт ArrayIterator автоматически в случаях, когда вы используете ArrayObject в цикле foreach или вызываете ArrayObject::getIterator() .

Имейте ввиду, что хотя ArrayObject и ArrayIterator ведут себя подобно массивам в контексте foreach , они всё-таки являются объектами. И если вы попытаетесь использовать с ними встроенные функции PHP вроде sort() and array_keys() , вы получите ошибку.

ArrayIterator прост в использовании, однако его возможности ограничены одномерными массивами. В случаях, когда вы имеете дело в многомерными массивами и вам необходимо обходить их рекурсивно, вам пригодится RecursiveArrayIterator .

Традиционным решением для обхода многомерных массивов можно считать вложенные циклы. Например:

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

С использованием RecursiveArrayIterator можно добиться более элегантного решения:

Вывод этого кода будет таким же, как и в предыдущем случае.

Обратите внимание на создание экземпляра RecursiveIteratorIterator и передачу ему объекта RecursiveArrayIterator . В противном случае вы получите только значения массива первого уровня и ряд уведомлений об ошибках.

Вам следует использовать RecursiveArrayIterator в случаях, когда имеете дело с многомерными массивами, поскольку он отлично справляется с рекурсивным обходом вложенных массивов. Однако, если в процессе обхода массива ему встретится итерируемый объект, то его обход — это уже ваша задача. Вот для этого случая и предназначен RecursiveIteratorIterator , который по сути является декоратором. В качестве аргумента он получает RecursiveArrayIterator , итерирует его, а также любой объект, реализующий интерфейс Iterable . Для того, чтобы в процессе итерации знать, на какой глубине в данный момент находится итератор, можно использовать метод RecursiveIteratorIterator::getDepth() . Будьте внимательны, работая с RecursiveArrayIterator и RecursiveIteratorIterator , когда имеете дело с объектами. Любой объект, реализующий Iterable , будет итерироваться тоже.

Итерация каталога файловой системы

Несомненно, любой программист время от времени сталкивается с необходимостью получения списка файлов в каталоге. Существует множество способов сделать это, используя, например, встроенные PHP-функции scandir() или glob() . Помимо них, вы также можете воспользоваться классом DirectoryIterator . Он довольно мощный сам по себе, но в случае необходимости вы можете его наследовать и расширять по своему усмотрению. Рассмотрим небольшой пример:

Неплохо для двух строчек кода? И не забывайте, что вдобавок вы теперь можете пользоваться исключениями:

Используя множество полезных методов вроде DirectoryIterator::isDot() , DirectoryIterator::getType() и DirectoryIterator::getSize() , вы можете получить практически всю информацию, которая только потребуется.

Если пойти дальше, то вы можете воспользоваться DirectoryIterator в связке с FilterIterator или RegexIterator , чтобы фильтровать результаты так. как вам нужно. Например:

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

Итоги

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

Топ-пост этого месяца:  Как редактировать главную страницу в wordpress 2 способа

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

FPublisher

Web-технологии: База знаний

Документация PHP

The DirectoryIterator >

Введение

>DirectoryIterator extends SplFileInfo implements Iterator , Traversable <

Содержание

  • DirectoryIterator::__construct — Constructs a new dir iterator from a path

  • DirectoryIterator::current — Return this (needed for Iterator interface)
  • DirectoryIterator::getATime — Get last access time of file
  • DirectoryIterator::getCTime — Get inode modification time of file
  • DirectoryIterator::getFilename — Return filename of current dir entry
  • DirectoryIterator::getGroup — Get file group
  • DirectoryIterator::getInode — Get file inode
  • DirectoryIterator::getMTime — Get last modification time of file
  • DirectoryIterator::getOwner — Get file owner
  • DirectoryIterator::getPath — Return directory path
  • DirectoryIterator::getPathname — Return path and filename of current dir entry
  • DirectoryIterator::getPerms — Get file permissions
  • DirectoryIterator::getSize — Get file size
  • DirectoryIterator::getType — Get file type
  • DirectoryIterator::isDir — Returns true if file is directory
  • DirectoryIterator::isDot — Returns true if current entry is ‘.’ or ‘..’
  • DirectoryIterator::isExecutable — Returns true if file is executable
  • DirectoryIterator::isFile — Returns true if file is a regular file
  • DirectoryIterator::isLink — Returns true if file is symbolic link
  • DirectoryIterator::isReadable — Returns true if file can be read
  • DirectoryIterator::isWritable — Returns true if file can be written
  • DirectoryIterator::key — Return current dir entry
  • DirectoryIterator::next — Move to next entry
  • DirectoryIterator::rewind — Rewind dir back to the start
  • DirectoryIterator::valid — Check whether dir contains more entries

Последние поступления:

ТехЗадание на Землю

Размещена 14 марта 2020 года

Пpоект Genesis (из коpпоpативной пеpеписки)

Шпаргалка по работе с Vim

Размещена 05 декабря 2020 года

Vim довольно мощный редактор, но работа с ним не всегда наглядна.
Например если нужно отредактировать какой-то файл например при помощи crontab, без знания специфики работы с viv никак.

Ошибка: Error: Cannot find a val >Размещена 13 сентабря 2020 года

Если возникает ошибка на centos 5 вида
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
Eg. Invalid release/

Linux Optimization

Размещена 30 июля 2012 года

Рекурсивный обход директории с помощью итераторов

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

Я попытался разобраться в этом вопросе, и всё что узнал делюсь.
Сначала я просто попытался пройтись по одной директории не исполmзуя рекурсию разными методами для определения удобства использования и скорости работы.

Проход директории с помощью родных методов

К родным (native) методам я отнес функции opendir(), closedir(), readdir() и rewinddir(). Больше казать об этих ф-циях нечего, чистая классика. Открыли каталог (если он существует), получили дескриптор (указатель) на него и начинаем с ним работать, по окончанию желательно закрыть каталог.

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

Проход директории с помощью предопределенного класса dir()


Предопределенных классов довольно много, они или являются родными, как класс dir(), Exception, Reflection, или такие которые подключаются с помощью соот. библиотек — mysqli, curl, GD и тд

Методы класса dir()

Название метода Описание метода
path путь к директории
handle ресурс, дескриптор
close() закрыть директорию
rewind() сброс дескриптора в начало директории
read() Чтение одного элемента директории и передвигаем указатель на одну позицию вниз.

Проход директории с помощью Итератора (DirectoryIterator)

Что есть итератор хорошо описано в Википедии не буду копи-пастить…

Класс DirectoryIterator реализует интерфейс итератора (могут проходить коллекцию в цикле foreach).

У данного класса уж очень много методов для работы с файлами и/или директориями. Постараюсь их все здесь описать. Некоторые из приведенных ниже относятся только в Unix подобным системам.

Методы класса DirectoryIterator()

Название метода Описание метода
getFilename() возврат имени файла или поддиректории
getBasename() похож на getFilename(), но может удалять суфикс,если таковой передать в виде параметра *
isDot() Определяет является ли текущий элемент «.» или «..»
rewind() сброс указателя на первый элемент
valid() проверка является ли текущий элемент правильным файлом.
Честно не понял.
key() возврат ключа текущего элемента
current() возврат текущего элемента
next() на 1 шаг вперед передвигает указатель
__toString() оопшный метод, приводит свойство к строке
getPath() возврат просто имени директории/файла и все
getPathname() возврат пути к файлу/директории+само название
getPerms() возврат прав доступа только для UNIX
getInode() х.з. что это, судя по названи наверное какое-то имя узла,
думаю только для UNIX
getSize() размер файла в байтах, для директории всегда ноль
getOwner() возврат имя владельца, только для UNIX
getGroup() возврат ИД группы, только для UNIX
getATime() последний доступ к файлу/директории в сек (начало с 1970)
getMTime() последний модификации файла/директории в сек (начало с 1970)
getCTime() последний изменения к файла/директории в сек (начало с 1970)
getType() возрат dir или file для сотв элемента.
isWritable() думаю понятно из названия, возврат истина/ложь
isReadable() думаю понятно из названия, возврат истина/ложь
isExecutable() думаю понятно из названия, возврат истина/ложь
isFile() думаю понятно из названия, возврат истина/ложь
isDir() думаю понятно из названия, возврат истина/ложь
isLink() думаю понятно из названия, возврат истина/лож,только для UNIX
getLinkTarget() для данных методов не нашел описание даже на оф.сайте.
getRealPath() для данных методов не нашел описание даже на оф.сайте.
getFileInfo() для данных методов не нашел описание даже на оф.сайте.
getPathInfo() для данных методов не нашел описание даже на оф.сайте.
openFile() для данных методов не нашел описание даже на оф.сайте.
setFileClass() для данных методов не нашел описание даже на оф.сайте.
setInfoClass() для данных методов не нашел описание даже на оф.сайте.

* — за подробностями обращайтесь к официальной документации.

Рекурсивный обход директории с помощью родных методов

Рассмотрев как можно пройтись по директории теперь рассмотри как можно пройтись абсолютно по всему каталогу.

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

Рекурсивный обход директории с помощью итератора (RecursiveDirectoryIterator)

Решение для обхода каталога на ООП нашлось и его скрипт ниже.

Красиво, всего одна строка, два класса и полный набор данных.

Из существующий методов , которые я уже не привожу, т.к. многие уже описал в других классах (key, current, rewind, valid etc), хотелось бы подчеркнуть метод setMaxDepth(integer); — он позволяет задать глубину прохода.

Другие методы которые есть у данного класса даже не описаны на оф. сайте.

Тесты

Как я их проводил. В цикле (1000) я засекал время перед открытие директории и после её закрытия. Затем я высчитывал среднее арифметическое. Т.к. результаты сильно зависят от железа (винчестера и др параметров), то приводить просто время в секундах не кошерно, поэтому я перевел их проценты. За 100% я принял время работы родных функций.

Проход 1000 раз директории $dir = ‘c:\\windows\\system32’;
native — 100%
dir() — 107%
DirectoryIteratior — 115%

Рекурсия директории $dir = ‘c:\\windows\\system32’;
native — 100%
RecursiveDirectoryIterator — 115%

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

UPD
Прошу прощения у общественности, я не верно провел тест с рекурсивным обходом.
Вот более детальные данные.
native — 100%
RecursiveDirectoryIterator — 185%

Как видно нативные фичи всегда рулят!

Статья просмотренна 80580 раз, зашло посетителей 20748

641 10 комментариев http%3A%2F%2Fblog.nagaychenko.com%2F2010%2F11%2F15%2F%25d1%2580%25d0%25b5%25d0%25ba%25d1%2583%25d1%2580%25d1%2581%25d0%25b8%25d0%25b2%25d0%25bd%25d1%258b%25d0%25b9-%25d0%25be%25d0%25b1%25d1%2585%25d0%25be%25d0%25b4-%25d0%25b4%25d0%25b8%25d1%2580%25d0%25b5%25d0%25ba%25d1%2582%25d0%25be%25d1%2580%25d0%25b8%25d0%25b8-iterator%2F %D0%A0%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B2%D0%BD%D1%8B%D0%B9+%D0%BE%D0%B1%D1%85%D0%BE%D0%B4+%D0%B4%D0%B8%D1%80%D0%B5%D0%BA%D1%82%D0%BE%D1%80%D0%B8%D0%B8+%D1%81+%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C%D1%8E+%D0%B8%D1%82%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%BE%D0%B2 2010-11-15+09%3A00%3A14 maxnag http%3A%2F%2Fblog.nagaychenko.com%2F%3Fp%3D641 в “Рекурсивный обход директории с помощью итераторов”

Конечно все зависит от поставленных задач, но RecursiveDirectoryIterator сильно начинает тормозить при глубине вложения директорий, хотя бы 3. Причем, оставание начинает рости в геометрической прогрессии при увеличении степени вложенности директорий.
Не знаю, как дела обстоят в php5.3.3 (как-то задач подобных не попадалось), но в свое время тестировал на php5.3.1 и все было довольно плохо.
Т.е. если вам не критично время выполнения скрипта и директорий не много, то использование RecursiveDirectoryIterator оправданно. Все просто и лаконично. Иначе, стоит 100 раз подумать прежде, чем использовать.

Топ-пост этого месяца:  Как можно вывести содержимое категории

Как-то не заметил. Проверю, самому интересно.

Спасибо за каммент

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

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

В БД при работе с камментами я не юзаю рекурсию, это очень наклдадно, использую другие известные методы.

Спасибо за ценную инфу на русском!

Надо различать задачи.
opendir — возвращает список файлов в директории.
RecursiveDirectoryIterator — возвращает ОБЪЕКТЫ. У которых есть свойства (размер, тип, права, владелец, группа и т.д.).
Если необходимо всё это, то костыли с opendir займут куда больше процессорного времени. Рекомендую добавить это в статью, и не вводить людей в заблуждение.

Мне кажется я четко описал, кто есть кто

К родным (native) методам я отнес функции opendir(), closedir(), readdir() и rewinddir(). Больше казать об этих ф-циях нечего, чистая классика.

Класс DirectoryIterator реализует интерфейс итератора …. Методы класса DirectoryIterator()

Тут чётко видно, кто есть ф-ция, а кто класс с методами? Что не так с Вашей точки зрения я не так сделал?

Да, видно. Было бы странно, если бы было непонятно, но проведённые тесты не совсем верны по описаным выше причинам. Попробуйте что нибудь такое сделать на родных методах, и с помощью DirectoryIterator:
https://dl.dropbox.com/u/585714/screenshots/Selec…

Результаты, я думаю, Вас удивят.:)

Что за дебильная привычка именовать переменные вроде idir? Что в этом сокращении содержится? Мы-ж не криптографы, а программисты. Правильно directoryIterator

Это не «дебильная привычка» — это опыт, например я понятие не имею какой тип данных в этой переменной, а по её названию я, иногда, могу понять, что i — это iterator. Также когда юзаешь название класса, у которого есть интерфейс часто пишут IClassName и первая буква означает Interface.

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


Difference between DirectoryIterator and FileSystemIterator

PHP 5 introduced DirectoryIterator, and PHP 5.3 introduced FileSystemIterator.

FileSystemIterator extends DirectoryIterator , but the documentation fails to say what extra features it brings.

Can you tell the difference between DirectoryIterator and FileSystemIterator ?

2 Answers 2

This goes out of the top of my head, where I sort of got caught in the changes prior to PHP 5.3 that were going to change in 5.3 and later, concerning the SPL (StandardPHPLibrary) and stuff that were going to be moved to the (horrible) PECL extensions.

The major thing that changed since 5.3, was that the SPL became an extension that could not be disabled anymore, see the changelog of 5.3 noting that

  • Added SPL to list of standard extensions that cannot be disabled. (Marcus)

so all the fancy classes like DirectoryIterator or SPLDoublyLinkedList were now a fix suite of classes that came with PHP 5.3.

There were a lot of discussions going on that the DirectoryIterator was still very clumsy in iterating over files/directories and from behaviour not anonymous enough to the filesystem being used. Because depending on the filesystem (Windows NTFS / *nix EXTx) the results the iterator would return were different from another, where *nix environments per default always resulted the dot and double dot directories ( . and .. ) as valid directories. These dot directories could then be filtered in the loop by using the isDot() method.

So FilesystemIterator became the new parent class in PHP 5.3, which prior to its release was the DirectoryIterator (where FilesystemIterator extends DirectoryIterator to implement this interchangeable behaviour by default). The behaviour, or result the FilesystemIterator produced, would then be equal to all different filesystems and interchangeable without the need of any overhead in the loop

It’s a good question why they didn’t update the documentation for noticing the user on the fact that actually the FilesystemIterator preceded the DirectoryIterator .

Разница между DirectoryIterator и FileSystemIterator

FileSystemIterator расширяется DirectoryIterator , но в документации не говорится, какие дополнительные функции он приносит.

Можете ли вы сказать разницу между DirectoryIterator и FileSystemIterator ?

2 ответа

DirectoryIterator является продолжением SplFileInfo

FilesystemIterator является продолжением DirectoryIterator

и оба инструмента

Iterator , Traversable , SeekableIterator

FilesystemIterator имеет флаги, которые влияют на его поведение при работе, какие файлы, которые могут быть очень полезны, такие как FOLLOW_SYMLINKS , SKIP_DOTS etc , и это делает большую часть его разницы.

Это выходит из верхней части моей головы, где я вроде как попал в изменения до PHP 5.3, которые должны были измениться в 5.3 и позже, относительно SPL (StandardPHPLibrary) и вещей, которые должны были быть перемещены в (ужасные) расширения PECL.

Главное, что изменилось с 5.3, было то, что SPL стал расширением, которое больше не может быть отключено, см. журнал изменений 5.3, отмечая, что

  • Добавлен SPL в список стандартных расширений, которые нельзя отключить.
    (Маркус)

таким образом, все модные классы, такие как DirectoryIterator или SPLDoublyLinkedList, теперь были набором исправлений классов, который поставляется с PHP 5.3.

Было много дискуссий о том, что DirectoryIterator все еще был очень неуклюж в итерации по файлам/каталогам и от поведения, недостаточно анонимного, до используемой файловой системы. Потому что в зависимости от файловой системы (Windows NTFS / *nix EXTx) результаты, возвращаемые итератором, отличались от других, где *nix среды по умолчанию всегда приводили к каталогам dot и double dot ( . и .. ) как допустимые каталоги. Эти каталоги точек могут быть затем отфильтрованы в цикле с помощью isDot() метода.

Таким FilesystemIterator образом, стал новый родительский класс в PHP 5.3, который до его выпуска был DirectoryIterator (где FilesystemIterator расширяется DirectoryIterator , чтобы реализовать это взаимозаменяемое поведение по умолчанию). Поведение, или результат FilesystemIterator произведенный, был бы тогда равным всем различным файловым системам и взаимозаменяемым без необходимости каких-либо накладных расходов в цикле

Хороший вопрос, почему они не обновили документацию для уведомления Пользователя о том, что на самом деле FilesystemIterator предшествовало DirectoryIterator .

FPublisher

Web-технологии: База знаний

Документация PHP

The DirectoryIterator >

Введение

>DirectoryIterator extends SplFileInfo implements Iterator , Traversable <

Содержание

  • DirectoryIterator::__construct — Constructs a new dir iterator from a path
  • DirectoryIterator::current — Return this (needed for Iterator interface)
  • DirectoryIterator::getATime — Get last access time of file
  • DirectoryIterator::getCTime — Get inode modification time of file
  • DirectoryIterator::getFilename — Return filename of current dir entry

  • DirectoryIterator::getGroup — Get file group
  • DirectoryIterator::getInode — Get file inode
  • DirectoryIterator::getMTime — Get last modification time of file
  • DirectoryIterator::getOwner — Get file owner
  • DirectoryIterator::getPath — Return directory path
  • DirectoryIterator::getPathname — Return path and filename of current dir entry
  • DirectoryIterator::getPerms — Get file permissions
  • DirectoryIterator::getSize — Get file size
  • DirectoryIterator::getType — Get file type
  • DirectoryIterator::isDir — Returns true if file is directory
  • DirectoryIterator::isDot — Returns true if current entry is ‘.’ or ‘..’
  • DirectoryIterator::isExecutable — Returns true if file is executable
  • DirectoryIterator::isFile — Returns true if file is a regular file
  • DirectoryIterator::isLink — Returns true if file is symbolic link
  • DirectoryIterator::isReadable — Returns true if file can be read
  • DirectoryIterator::isWritable — Returns true if file can be written
  • DirectoryIterator::key — Return current dir entry
  • DirectoryIterator::next — Move to next entry
  • DirectoryIterator::rewind — Rewind dir back to the start
  • DirectoryIterator::valid — Check whether dir contains more entries

Последние поступления:

ТехЗадание на Землю

Размещена 14 марта 2020 года

Пpоект Genesis (из коpпоpативной пеpеписки)

Шпаргалка по работе с Vim

Размещена 05 декабря 2020 года

Vim довольно мощный редактор, но работа с ним не всегда наглядна.
Например если нужно отредактировать какой-то файл например при помощи crontab, без знания специфики работы с viv никак.

Ошибка: Error: Cannot find a val >Размещена 13 сентабря 2020 года

Если возникает ошибка на centos 5 вида
YumRepo Error: All mirror URLs are not using ftp, http[s] or file.
Eg. Invalid release/

Linux Optimization

Размещена 30 июля 2012 года

Топ-пост этого месяца:  JoomShopping — установка бесплатного компонента интернет-магазина на Joomla и его первоначальная

Разница между DirectoryIterator и FileSystemIterator

В PHP 5 был представлен DirectoryIterator , а в PHP 5.3 — FileSystemIterator .

FileSystemIterator расширяет DirectoryIterator , но в документации не сказано, какие дополнительные функции он предоставляет.

Можете ли вы сказать разницу между DirectoryIterator и FileSystemIterator ?

2 ответа

Это выходит из головы, где я как бы попал в изменения до PHP 5.3, которые должны были измениться в 5.3 и позже, в отношении SPL (StandardPHPLibrary) и вещей, которые собирались перенести в ( ужасно) расширения PECL.

Главное, что изменилось с 5.3, это то, что SPL стал расширением, которое больше нельзя было отключить, см. Список изменений 5.3, отмечая, что

  • Добавлен SPL в список стандартных расширений, которые нельзя отключить. (Марк)

так что все модные классы, такие как DirectoryIterator или SPLDoublyLinkedList, теперь были фиксированным набором классов, поставляемых с PHP 5.3.

Было много дискуссий о том, что DirectoryIterator по-прежнему очень неуклюже перебирает файлы / каталоги, и от поведения, недостаточно анонимного до используемой файловой системы. Поскольку в зависимости от файловой системы (Windows NTFS / * nix EXTx) результаты, которые должен возвращать итератор, отличаются от других, где среды *nix по умолчанию всегда приводят каталоги с точками и двойными точками ( . И .. ) в качестве допустимых каталогов. Эти точечные каталоги могут быть затем отфильтрованы в цикле с помощью isDot() .

Таким образом, FilesystemIterator стал новым родительским классом в PHP 5.3, который до его выпуска был DirectoryIterator (где FilesystemIterator расширяет DirectoryIterator для реализации этого взаимозаменяемого поведения по умолчанию ). Поведение или результат, создаваемый FilesystemIterator , будет тогда равен всем различным файловым системам и будет взаимозаменяемым без каких-либо накладных расходов в цикле.

Это хороший вопрос, почему они не обновили документацию, чтобы заметить пользователя о том факте, что фактически FilesystemIterator предшествовал DirectoryIterator .

Файловая система PHP

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

Открытие файла с помощью функции PHP fopen()

Для работы с файлом сначала нужно его открыть функцией fopen() . Ее синтаксис:

Первый параметр, передаваемый в fopen() , это имя файла, который нужно открыть, а второй — режим открытия. Например:

Файл может быть открыт в одном из следующих режимов:

Режим Что он делает
R Открывает файл только для чтения.
r+ Открывает файл для чтения и записи.
W Открывает файл только для записи и очищает содержимое файла. Если файл не существует, PHP попытается его создать.
w+ Открывает файл для чтения и записи и очищает содержимое файла. Если файл не существует, PHP попытается его создать.
A Открывает файл только для записи. Сохраняет содержимое файла, записывая его в конец файла. Если файл не существует, PHP попытается его создать.
a+ Открывает файл для чтения и записи. Сохраняет содержимое файла, записывая его в конец файла. Если файл не существует, он будет создан. Можно использовать вместо PHP fread ()
X Открывает файл только для записи. Возвращает значение FALSE и генерирует ошибку, если файл уже существует. Если файл не существует, PHP попытается его создать.
x+ Открывает файл для чтения и записи; в противном случае имеет такое же поведение, как «x».

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

Совет . Операции с файлами и папками часто сопряжены с ошибками. Поэтому рекомендуется применить форму проверки ошибок, чтобы при их возникновении скрипт обработал ошибку.

Закрытие файла

Как только вы закончите чтение файла с помощью PHP fread , его нужно закрыть. Для этого используется функция fclose() :

Примечание . Хотя PHP автоматически закрывает все открытые файлы, когда скрипт завершается, рекомендуется закрыть файл после выполнения всех операций.

Чтение из файлов с помощью функции PHP fread()

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

Чтение фиксированного количества символов

Функция PHP fread() может использоваться для чтения заданного количества символов из файла. Базовый синтаксис функции:

Она принимает два параметра — дескриптор файла и количество байтов, которые должны быть считаны. В следующем примере мы считываем 20 байтов из файла data.txt , включая пробелы. Предположим, data.txt содержит абзац текста « The quick brown fox jumps over the lazy dog «:

Приведенный выше пример даст следующий результат:

Чтение всего содержимого файла

Функция fread() может использоваться в связке с функцией filesize() для полного считывания всего файла. filesize() возвращает размер файла в байтах. PHP fread пример:

Приведенный выше пример даст следующий результат:

Самый простой способ прочитать все содержимое файла — это функция readfile() . Она позволяет считать содержимое файла, не открывая его. Следующий пример даст тот же результат, что и предыдущий пример:

Приведенный выше пример даст следующий результат:

Другой способ прочитать все содержимое файла, не открывая его — это функция file_get_contents() . Она принимает имя и путь к файлу и считывает весь файл в строковую переменную. Пример без PHP fread :

Еще один способ считывания всех данных из файла — это функция file() . Она работает аналогично функции file_get_contents() , но возвращает содержимое как массив строк, а не одну строку. Каждый элемент возвращаемого массива соответствует строке в файле.

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

Запись файлов с использованием функции PHP fwrite()

Можно записать данные в файл с помощью функции PHP fwrite() . Ее синтаксис:

Функция fwrite() принимает два параметра: дескриптор файла и строку данных, которые должны быть записаны:

В приведенном выше примере, если файл note.txt не существует, PHP автоматически создаст его и запишет данные. Но если note.txt уже существует, PHP перед записью новых данных стирает содержимое этого файла. Если вы просто хотите добавить файл и сохранить существующее содержимое, используйте режим a вместо w .

Альтернативный способ – file_put_contents() . Это аналог функции file_get_contents() , который предоставляет простой способ записи данных в файл без необходимости его открытия. Эта функция принимает имя и путь к файлу с данными, которые должны быть записаны. Например ( похожий на PHP fread пример ):

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

Переименование файлов с помощью функции PHP rename()

После прочтения с помощью php fread() файл можно переименовать файл или каталог, используя функцию PHP rename() , например:

Удаление файлов с помощью функции PHP unlink()

Можно удалять файлы или папки с помощью функции PHP unlink() , например:

Функции файловой системы PHP

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

Функция Описание
fgetc() Считывает один символ за раз.
fgets() Считывает одну строку за раз.
fgetcsv() Считывает строку разделенных запятыми значений.
filetype() Возвращает тип файла.
feof() Проверяет, достигнут ли конец файла.
is_file() Проверяет, является ли файл стандартным файлом.
is_dir() Проверяет, является ли файл каталогом.
is_executable() Проверяет, является ли файл исполняемым.
realpath() Возвращает канонизированный абсолютный путь к файлу.
rmdir() Удаляет пустую директорию.

Данная публикация представляет собой перевод статьи « PHP File System » , подготовленной дружной командой проекта Интернет-технологии.ру

Класс PHP: DirectoryIterator – удобный интерфейс

#1 MonstrMoney

  • Пользователи
  • 55 357 сообщений
  • 0 спасибо
  • Класс PHP: DirectoryIterator – удобный интерфейс

    Как создать сайт. Основы Самостоятельного Сайтостроения

    Опубликовано: 25 мая 2015 г.

    Ссылка на курс: webformyself.com/directoryiter.

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

    Добавить комментарий