Имитация файлов и директорий PHP

Уроки PHP.

Урок 6. Файлы, директории и PHP


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

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

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

file_exists

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

if ( !file_exists(«somefile.txt») ) exit(«Указанный файл не существует»);

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

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

Просто указание имени файла означает, что он находится в текущей директории.

Файл содержится в папке files, находящейся в текущей директории. Длина цепочки из папок не ограничена.

Файл лежит в предыдущей директории. Каждый знак ../ расценивается как возврат в родительскую директорию.

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

filesize

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

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

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

$text_file = implode(«», file(«somefile»));
echo $text_file;

readfile

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

$bytes = readfile («somefile»);
echo «Итого — «.$bytes.» символов»;

fopen

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

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

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

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

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

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

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

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

fgets

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

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

$file = fopen («somefile», «r»);
while ($line = fgets($file, 4096) )
<
$line.=»\n»;
echo $line;
>
следующие команды работы с файлом

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

fputs

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

fclose

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

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

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

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

opendir

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

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

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

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

readdir

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

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

closedir

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

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

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

Для чтения содержимого директории в PHP есть старые проверенные функции readdir, opendir и closedir. Не все до сих пор знают, но в 5 версии появилось нечто более мощное — итераторы. С их помощью рутинная работа по поиску файлов намного упростилась и стала в несколько раз быстрее. Рассмотрим пример, как с помощью итератора прочитать все содержимое каталога

Как видим все просто, нужно только знать когда какой итератор использовать, его разрешенные флаги и как их можно совмещать. Рассмотрим основные флаги

  • FilesystemIterator::SKIP_DOTS — указывает, что нужно пропустить текущую (.) и родительскую директории (..)
  • FilesystemIterator::FOLOW_SYMLINKS — указывает, что нужно идти по символьным ссылкам и выводить их содержимое
  • RecursiveIteratorIterator::SELF_FIRST — указывает на то, что нужно показать сначала родительские элементы, а потом дочерние
  • RecursiveIteratorIterator::CATCH_GET_CHILD — если у итератора не будет прав на чтение какой-либо директории, он просто пропустит ее
  • RecursiveIteratorIterator::LEAVES_ONLY — показывает только файлы
  • RecursiveIteratorIterator::CHILD_FIRST — указывает на то, что нужно показать сначала дочерние элементы, а потом родительские

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

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

Итераторы в Symfony

В Symfony начиная из первых версий был компонент sfFinder, думаю он многим знакомый. Этот класс очень удобный для поиска файлов и каталогов по заданным критериям. По своей сути он похож на команду find в Linux. А основной плюс, что его можно использовать отдельно от Symfony. Например, что-то вроде этого

Мастер Йода рекомендует:  10 лучших видео об анализе данных на YouTube

Интерфейс простой и понятный, возвращает массива файлов и директорий соответствуючих критерию поиска. Но он использует старый механизм opendir, readdir, closedir.

Думаю именно по-этому он был переписан во второй версии Symfony — теперь он использует итераторы и работает быстрее. Поскольку Symfony 2.0 написан на PHP 5.3, то нужно помнить про неймспейсы. Например

Пример выше выведет рекурсивно на экран все файлы из текущей директории. Почти все методы класса возвращают экземпляр объекта, исключением является метод in, который возвращает итератор для заданного каталога. Рассмотрим пример

Этот код исчет файлы, имя которых test с любым расширением, кроме файлов ruby, идет по символьным ссылкам, фильтрует по размеру и пропускает файлы систем контроля версий (svn например). Фильтровать можно также при помощи анонимной функции

Как видим итераторы очень гибкое и мощное дополнение в PHP и доказательством этого есть класс Finder в Symfony 2.0

Рекурсивный поиск файлов в директории PHP

Приветствую! Сегодня я хотел бы поделится решением проблемы поиска файлов с которой мне пришлось столкнутся по работе.

Описание проблемы.

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

Случай был не самый простой и я приступил к реализации решения.

Решение.

Далее я распишу ход процесса и буду снабжать участки кода комментариями.

Начинаем мы с того что получим путь до нужной нам директории. Методы получения пути до нее у вас могут отличаться.

Путь по которому будем искать файлы у нас есть, теперь приступим к написанию функции для поиска по этому пути.

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

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

Вот как это выглядит:

Итак. Каркас функции у нас есть, приступим к её наполнению.
Для начала нам нужно проверять имеющийся у нас путь на то является он директорией или файлом.

Предположим что наш путь является папкой, далее на нужно разбить этот путь на входящие в него файлы и папки.
В этом нам может помочь отличная php функция scandir ($path). Она анализирует переданный путь и возвращает массив содержащий в себе названия папой и файлов находящихся по переданному пути.

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

В нашем случае они не нужны и мы удаляем их из результата работы scandir ($path).

Теперь у нас есть массив содержащий данные вида: [‘files’ , ‘file.js’ , ‘index.html’]. Нас это устраивает и мы можем переходить к этапу перебора этого массива.

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

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

В конечно итоге наша конструкция будет выглядеть так:

На этом пожалуй все. Надеюсь мой опыт будет вам полезен. Успехов!

dmkweb.ru Права на контент защищены.

Подписаться на обновления блога

Похожие записи:
Добавить комментарий
комментариев 5

Как интересно! Спасибо!

что такое $files = [];

Усіх грошей не заробиш — частину доведеться вкрасти. — Технічно, — сказав кінь, — я підкований.

Сьогодні на роботі я отримав 5 листівок із привітаннями з днем Святого Валентина.
Шкода, що глухому нашому колективі немає жінок.

Краще сім разів покритися потом, ніж один раз інеєм! — Для мене було розчаруванням дізнатися, що ти працюєш глухому Макдональдсі.
— Великим, крихітним, або середнім?

Також пропоную почитати — Нижегородський водій-інвалід намагається відновити справедливість і повернути свої права (2 фото + відео), детальніше тут http://belosnet.dn.ua/nizhegorodskij-vodij-invalid-namagayetsya-vidnoviti-spravedlivist-i-povernuti-svoyi-prava-2-foto-video/, тут багато цікавого.

Мишко, Мишко, де твоя ощадкнижка,
Повна червінців і рублів?
Сама безглузда помилка, Мишко,
Або, що ти їх витрачаєш на б.

Приїжджайте до мене глухому гості з тортиком, поставимо його глухому холодильник, і будемо жерти горілку.

Я Навчив промовляє папугу Спасибі, він мені вдячний Скрізь пишуть, що треба рухатися вгору і вгору. Але коли ти глухому сраці, так хочеться вниз, до виходу. Все, що не робиться — до кращого. Просто не завжди до вашого.

Страшне одеське прокляття:
— Шоб ти був такий розумний, як моя дружина потім! — Вовочка, а хто твій тато працює?
— Він соліст!
— А співає він де?
— На овочебазах, коли солить капусту! Не знаю, як щодо любові, а ось стояк з першого погляду — це цілком реально. У посадових осіб такі особи, як ніби всі їм винні. Глухому Москві пройшов «Марш материнського гніву». Кілька поліцейських отримали ременя.

Найгірше глухому відключенні інтернету, це або що про це відключенні ми не зможемо написати. Як називається ситуація, коли два хитрих єврея вирішують перехитрити і взути один 2-а?
— ДрузьБер! Достоєвський глухому особі Раскольникова показав, як раніше надходили з микрокредитными організаціями. Розмір «Ніхто не скаржився». Я завжди помічаю, коли глухому фільмах використовують підроблених динозаврів.

— Розочка, а правда, що вас Семен кинув?
— Ой, прямо-таки кинув! Він мене навіть підняти не зміг! Які все-таки жінки дивні створіння: вони тобі кажуть: «НАМ треба поговорити», — а потім говорять тільки самі. — Алло, дівчина, якими надійними засобами контрацепції ви користуєтеся?
— Доктор, я потвора. — Доктор, мій чоловік зовсім не вміє пити. Вип’є 3 стопки і каже, що йому вистачить. Соромно з ним глухому гості прогулюється.

— Чому я тобі сподобалася?
— Ну, ти красива і працюєш.

Вывод файлов из директории

Есть такой вопрос: имеется директория и в ней текстовые файлы.
Надо вывести названия этих файлов с ссылкой на каждый файл.
Вот примерно такой код:

20.12.2014, 01:04

Вывод файлов pdf в директории
Есть директория в которой лежат файлы pdf, в ней же нужно сделать файл index.php который выведет.

Поиск вхождений в файлах директории и вывод файлов на экран
Здравствуйте, уважаемые форумчане! Возник вопрос: Предположим, у меня на сервере есть директория с.

Вывод списка файлов из директории с указанием даты создания и размером файла
Доброго времени суток! Помогите решить задание. Нужно вывести на экран список файлов из директории.

Реализовать вывод файлов директории и её поддиректорий в массив
Буду очень благодарен за подсказку как реализовать вивод файлов в масив, но тут есть одно «но».

20.12.2014, 01:33 2 20.12.2014, 13:03 3

Еще нужно проверить, файл ли.

Виталюска, что-то не догнал, как вы тут использовали strpos.

P.S. Что за болезнь везде использовать динамические параметры. Уж здесь-то точно гораздо уместнее использовать пути.

20.12.2014, 14:31 4
20.12.2014, 14:31
22.12.2014, 23:45 [ТС] 5

Виталюска,
Здравствуйте!
А вы не подскажете как сделать так: имеется директория и в ней набор файлов.
Хотел бы сделать так: раскидать файлы в файл index.php? > Как можно это сделать?

23.12.2014, 11:49 6

miketomlin, ну так в чем проблема напишите человеку код, зачем только разводить базар

Добавлено через 2 минуты
ollegra77, как вариант при сохранении присваивать файлу номер

23.12.2014, 13:12 7

Сначала базар, потом код, не?

Отсортируйте массив, оставив в нем только имена txt-файлов. Индексы элементов массива можно использовать в качестве id файлов. Это при условии, что в дальнейшем состав файлов изменяться не будет. В массив можно было сразу втягивать только txt-файлы при помощи opendir/readdir/closedir.

Добавлено через 5 минут
А вообще я не совсем понимаю, что значит «раскидать файлы в файл index.php? >

23.12.2014, 16:53 [ТС] 8

Здравствуйте!
Да, имел ввиду отдавать файлы по запросу «index.php? > Не подскажете на коде?

Добавлено через 39 секунд
miketomlin,
Здравствуйте!
Да, имел ввиду отдавать файлы по запросу «index.php? > Не подскажете на коде?

23.12.2014, 17:54 9

На коде не подскажу. Подскажу, как это можно сделать.

PHP Текущее местоположение скрипта, папки, имя файла

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

Как в PHP узнать полный путь к файлу или папке

Для начала приведу примеры, что вы получите вызвав соответствующие константы:

Мы рассмотрели 2 константы, __FILE__ и __DIR__ для отображения полного пути к текущему файлу и папке (директории). Стоит отметить, что __DIR__ эквивалентен вызову:

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

Что мы еще можем применить для константы __FILE__? Конечно же отделить путь и получить просто имя файла:

basename — функция возвращает последний элемент из пути, который, как правило, и является именем файла. Раз уж мы решили писать функции заменители, давайте рассмотрим наш URL, как массив, разделенный слешами («/»):

Как видим, последний элемент массива является нашим файлом. Чтобы получить последний элемент массива, не зная его количество, пишем:

Минус 1 потому как отсчет для массивов идет с нуля, но при счете всегда стартует с единицы.
Важно — в некоторых указаниях полного пути вы используете разделители (вышеупомянутые слеши ‘/’). Но, для Windows это «\», для Linux и остальных — «/». Есть такая константа:

Вернет 1 слеш (без кавычек).

Немного закрепим 2 функции, о которых шла речь выше:
str_replace — функция, которая используется для замены в строке. Первый параметр «что ищем», затем «на что меняем» и последний «где ищем», в который мы и передали нашу полную строку.
explode — функция, которая делает из строки массив. Но, чтобы функции понять как разбить строку — ей нужно передать «разделитель», а уже вторым параметром — саму строку.

Как вы заметили, «/home/bitrix/www» — это путь на самом сервере, который можно «вырезать» как раз при помощи str_replace.
Если вам нужно использовать «текущий домен», то получить его при помощи PHP можно несколькими способами. Один из них:

Надеюсь вам эта тема была интересна. Пишите в комментариях как вам формат, и нужен ли он вообще. А то в последнее время только битрикс да битрикс :).

автор: Dmitriy

Занимаюсь веб-разработкой с 2011 года. Посмотреть некоторые из моих работ, а также узнать чуть больше обо мне, вы можете на forwww.ru.

Какие услуги предоставляю:
— Создание сайтов, шаблонов и компонентов на 1С-Битрикс;
— Разработка функционала с нуля и доработка кода на уже созданных проектах;
— Адаптивная вёрстка макетов и натяжка на Битрикс;
— Парсинг файлов и выгрузка на сайт (форматы — CSV, XML, XLSX, JSON)
— Интеграции со сторонними сервисами по API;
— Многоязычные версии и многое другое.

PHP вывод файлов и каталогов директории

Часто в PHP нужно вывести все файлы и каталоги в виде списка. это нужно, чтобы нам сразу узнать где у нас, чего и сколько. давайте приступать.

Сегодня saitsozdanie.ru рассмотрит несколько способов:

1 способ) Выводим только файлы с расширением php (например)

$filelist = glob(«*.php»);
foreach ($filelist as $filename) <
echo $filename.» и его размер: «.filesize($filename).» байт
«;
>

Также можно вывести файлы любого расширения txt например и тд. Дело в том, что функция glob() — предназначена для вывода по шаблону. (Если поставить так me* — то будут выводиться все файлы начинающиеся на «me»)

2 способ) Выводим все файлы в данной папке:

$path = «.»;
$filelist = array();

if($handle = opendir($path)) <
while($entry = readdir($handle)) <
echo $entry.»
«;
>

Тут мы используем функции opendir(), для открытия файла. далее можно сразу использовать функцию readdir(), которая шаг за шагом будет считывать по одному файлу и наполнять наш массивчик $filelist, и в конце закрываем открытую папочку с помощью функции closedir(). Если в $path = «.» вместо точки поставить files — то будут считываться все файлы из папки по имени files.

3 способ) Задействуем функцию scandir()

Функция scandir() — принимает лишь путь или место, где нужно искать и получает массив с данными, который перебрав можно получить файлы и папки в алфавитном порядке. scandir(«.») — будет искать в той же категории, что и сам исполняемый файл.

4 способ) использование функции с задействованием цикла for

function nav($dir) <
if(is_dir($dir)) <
$files = scandir($dir);
array_shift($files); // удаляем из массива ‘.’
array_shift($files); // удаляем из массива ‘..’

5способ) Ну и напоследок самый верный по мнению многих профессионалов способ для чтения каталога на php:

$dir = «files»;
if($handle = opendir($dir))<

Какой вам проще выбирайте.

Более новые статьи:

  • Часто возникает вопрос: «Как убрать копейки из цены на php?» на него и будет отвечать в этой статье на примере одной cms. …

«>Как убрать копейки из цены на php — 14/03/2020 10:10
Без соединения с базой данных (БД) сегодня не работает практически ни один сайт. поэтому и мы рассмотрим как соединяться с MySQL при помощи php. …

«>Создание соединения с БД MySQL разными способами — 09/03/2020 19:06
Для тех, кто только начинает изучать PHP — заголовки HTTP является каким-то туманом, который почему-то не особо приятный. давайте его рассеивать. Люб …

Более старые статьи:

  • На PHP часто нужна загрузка файлов на сервер. приятно же, если у вашего сайта есть возможность загружать файлы на сайт: картинки или другие текстовые …

«>PHP Загрузка файлов на сервер
В PHP часто приходится иметь дело с созданием файла. все очень просто нет файла на диске, код прогнался и файл появился, далее можно считать этот фай …

«>php создание файла, чтение и запись
Конструкция switch — переключатель на php бывает в некоторых случаях незаменима, и увеличивает быстродействие. …

имитация директорий и файлов

Имитирую директории и файлы , таким кодом

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

ashenemy, есть два универсальных решения
1ый вариант — это добавить условие по расширению файла

2-ой, это проверять на существование файла

столкнулся с такой проблемолй, есть код

проблема в том, что он видя, accaunt/private/ уже не идет,
открывая accaunt.php?action=mes
как сделать чтобы если указан просто /accaunt/private/ открывалась одна страница
е если указан /accaunt/private/send.html открывалась другая

А причем тут переносимость? Правила они для всех одинаково писаны.

Только вот
RewriteRule ^accaunt/private/outbox.html accaunt.php?action=ish
Посчитает запрос accaunt/private/outbox.html?orly=yarly правильным, а
RewriteRule ^accaunt/private/outbox.html$ accaunt.php?action=ish нет

Как это использовать и есть-ли от этого хоть какая-то польза решать вам )

PHP :: Редактирование содержимого файла

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

  • (от англ. file descriptor) – неотрицательное целое число, которое операционная система возвращает при открытии файла (в случае, если это возможно) и с помощью которого выполняются все остальные файловые операции. По завершении операций и закрытии файла дескриптор теряет смысл.
  • – число, указывающее величину смещения относительно нулевого байта в файле. Обычно по этому адресу осуществляется чтение/запись, если конечно вызов операции чтения/записи не предусматривает указание адреса. При выполнении операций чтения/записи файловый указатель смещается на число прочитанных/записанных байт. В результате последовательный вызов операций чтения позволяет прочитать весь файл не обращая внимания на его размер.
  • – специально выделенный участок памяти (буфер), в котором операционная система осуществляет кэширование файловых операций. При закрытии файла буфер сбрасывается.
  • – режим устанавливающий разрешения на чтение и запись файла при его открытии.

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

  • ‘r’ – открывает файл только для чтения и помещает указатель в начало файла;
  • ‘r+’ – открывает файл для чтения и записи и помещает указатель в начало файла;
  • ‘w’ – открывает файл только для записи, помещает указатель в начало файла и обрезает файл до нулевой длины; если файл не существует – пытается его создать;
  • ‘w+’ – открывает файл для чтения и записи, помещает указатель в начало файла и обрезает файл до нулевой длины; если файл не существует – пытается его создать;
  • ‘a’ – открывает файл только для записи и помещает указатель в конец файла; если файл не существует – пытается его создать;
  • ‘a+’ – открывает файл для чтения и записи и помещает указатель в конец файла; если файл не существует – пытается его создать;
  • ‘x’ – создаёт и открывает файл только для записи и помещает указатель в начало файла; если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выведет ошибку; если же файл не существует, то функция попытается его создать;
  • ‘x+’ – создаёт и открывает файл для чтения и записи и помещает указатель в начало файла; если файл уже существует, вызов fopen() закончится неудачей, вернёт FALSE и выведет ошибку; если же файл не существует, то функция попытается его создать;
  • ‘c’ – открывает файл только для записи, помещает указатель в начало файла, но сам файл при этом в отличие от режима доступа ‘w’ не обрезается, а вызов к этой функции не вызывает ошибку; если файл не существует, то он создается;
  • ‘c+’ – открывает файл для чтения и записи, помещает указатель в начало файла, но сам файл при этом в отличие от режима доступа ‘w+’ не обрезается, а вызов к этой функции не вызывает ошибку; если файл не существует, то он создается.

Поскольку различные операционные системы имеют собственные соглашения по обозначению конца строки, следует быть внимательным при записи данных в текстовый файл, правильно устанавливая символы конца строки в соответствии с операционной системой, под которой работает скрипт: ‘\n’ для Unix/Linux , ‘\r\n’ для Windows и ‘\r’ для Macintosh . Также рекомендуется при использовании данной функции устанавливать флаг трансляции, который может принимать два значения: ‘t’ , которое предназначено для автоматического перевода ‘\n’ в ‘\r\n’ в текстовых файлах в случае работы скрипта под Windows , и ‘b’ , которое устанавливает бинарный режим обработки файла (например, изображения), не предусматривающий преобразования данных и оперирующий не символами, а байтами. Для задания любого из этих режимов, следует просто дописать соответствующий флаг в строке с режимом доступа, например, ‘rt’ или же ‘wb’ . Полагаться на первое значение не стоит, поэтому рекомендуется всегда применять бинарный режим обработки файлов, правильно обрабатывая символы конца перевода строк. Помочь в этом может, например, специальная константа PHP_EOL , которая содержит корректный символ конца строки, используемый на данной платформе.

Рассмотрим использование функции fopen() на примере №1.

Пример №1. Использование функции fopen()

После того, как файл будет успешно открыт, fopen() вернет дескриптор файла, который будет доступен другим функциям для работы с содержимым файла вплоть до его закрытия при помощи функции fclose() . Пусть, например, у нас имеется обычный текстовый файл test.txt (см. пример №2).

Пример №2. Содержимое текстового файла test.txt

Рассмотрим на его примере некоторые имеющиеся возможности для чтения файлов (см. пример №3).

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

Имеются в PHP и функции для записи данных в файл (см. пример №4). При этом следует помнить, что при открытии файла для записи нужно выбирать соответствующий режим записи. Например, если данные должны быть дописаны в файл, а не перезаписаны, то режим ‘w’ не подойдет, поскольку в этом случае файловый указатель будет помещен в начало файла, а сам файл будет урезан до нулевой длины.

PHP. Как проверить существует папка или нет. И если нет, то создать ее

Проверяем, существует директория или нет? Если такой директории нет, создает ее.

Функция is_dir(), позволяет узнать, является ли имя файла директорией. Если такой директории нет, то создаем новую с помощью функции mkdir().

Функция file_exist(), проверяем существование указанного файла или каталога. Если такой директории нет, то создаем новую с помощью функции mkdir().

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

Прочитать список файлов и поддиректорий, находящихся по заданному пути можно с помощью трех основных встроенных функций PHP: scandir(), glob() и readdir(). Каждая из этих функций полезна по своему и применять их нужно в зависимости от поставленной задачи. Методы использования и отличия в функциях PHP scandir(), glob() и readdir() и будут рассмотрены ниже.

Получить список файлов и директорий на PHP можно с помощью встроенной функции PHP glob(). Официальная документация использования функции glob() находится тут .

В результате выполнения функции glob() будет получен массив, содержащий все каталоги и почти все файлы, заданной в переменной $path директории, без элементов «.», «..» (точка — указывает на текущую директорию, две точки — предыдущая директория), которые, к примеру, будут прочитаны при использовании функции readdir() или scandir(). Почти все, а не все файлы будут получены потому, что шаблон «*» не включает файлы, начинающиеся с символа точки, например: .htaccess. Чтобы получить список всех файлов — можно использовать шаблон с константой, опубликованные ниже:

При использовании шаблона <,.>будут показаны не только файлы, начинающиеся с точки, но и директории-точки (точка и две точки, если есть вышестоящая директория) — при необходимости их нужно дополнительно отфильтровать, например при помощи условного оператора if().

Вообще, функция glob() существует для поиска файлов и директорий, в соответствии с заданным шаблоном. То есть с ее помощью лучше искать, например, все файлы с расширением jpg. Казалось бы, нет ничего проще: указываем шаблон *.jpg и ищем, но если расширение файла написано не только прописными буквами, например Jpg, то в регистрозависимых файловых системах, таких, как в операционных системах FreeBSD, Linux и подобных, это задание вызовет некоторые трудности. Пример, задания регистронезависимого поиска по шаблону — нужно найти все файлы, с расширением jpg, JPG, jPG и подобные:

Более подробнее про синтаксис шаблона glob() можно прочитать тут: » Основы Linux от основателя Gentoo. Glob-подстановки «.

Если порядок сортировки файлов и директорий на выходе функции glob() не важен — необходимо использовать константу GLOB_NOSORT. В этом случае функция будет работать заметно быстрее.

Scandir

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

Readdir

С помощью функции readdir() также можно просмотреть список файлов и директорий по заданному пути. Вот только для неё необходима специальная обертка. Актуальную информацию по использованию readdir() можно посмотреть в официальной документации PHP тут .

Не смотря на то, что для использования readdir() необходимо использовать больше строк кода, в некоторых случаях её применение остается актуальным. Прочитав статью на сайте lab.ixblogs.com можно выяснить, что скорость работы readdir() выше, чем у аналогичных функций PHP.

Примеры использования функций

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

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

// $path — путь к директории
// $pattern — шаблон поиска
// $flags — константа для функции glob()
// $depth — глубина вложенности, просматриваемая функцией. -1 — без ограничений.
function bfglob ( $path , $pattern = ‘*’ , $flags = GLOB_NOSORT , $depth = 0 )
<
$matches = array ( ) ;
$folders = array ( rtrim ( $path , DIRECTORY_SEPARATOR ) ) ;

while ( $folder = array_shift ( $folders ) )
<
$matches = array_merge ( $matches , glob ( $folder . DIRECTORY_SEPARATOR . $pattern , $flags ) ) ;
if ( $depth != 0 )
<
$moreFolders = glob ( $folder . DIRECTORY_SEPARATOR . ‘*’ , GLOB_ONLYDIR ) ;
$depth = ( $depth — 1 ) ? — 1 : $depth + count ( $moreFolders ) — 2 ;
$folders = array_merge ( $folders , $moreFolders ) ;
>
>
return $matches ;
>

$file = bfglob ( ‘my_dir’ , «*» , GLOB_NOSORT , — 1 ) ;
print_r ( $file ) ;

Стоит обратить внимание, на константу DIRECTORY_SEPARATOR, использующуюся в функции bfglob(). Эта константа хранит символ, разделяющий директории, для операционной системы, под управлением которой запущен скрипт: например Linux понимает только «/», Windows, по умолчанию использует разделитель директорий «\», но понимает и «/». Если функция bfglob() будет запускаться из под различных операционных систем, с последующим хранением результатов работы — желательно заменить константу DIRECTORY_SEPARATOR на символ «/», чтобы избежать проблем с несовместимостью путей.

Рекурсивное удаление файлов и директорий

Как удалить не пустую директорию с использованием PHP? Ниже — пример двух функций, которые извлекают списки путей ко всем файлам и директориям. Отличия от пользовательской функции bfglob() — на выходе пути к директориям и файлам лежат в разных ячейках массива и подсчитывается общий объем занимаемого файлами места. Если раскомментировать unlinc() и rmdir() — будут также удалены все файлы, по заданному пути. ВНИМАНИЕ: перед тем, как запустить процесс удаления файлов и директорий следует несколько раз проверить, что вы собираетесь удалить именно то, что нужно!

$dir = ‘MyDir’ ;
function remove_all_g ( $dir , $result = array ( ) )
<
if ( $paths = glob ( $dir . ‘/*’ , GLOB_NOSORT ) )
<
foreach ( $paths as $path )
<
if ( is_dir ( $path ) )
<
$result = remove_all_g ( $path , $result ) ;
>
else
<
$result [ ‘path’ ] [ ‘file’ ] [ ] = $path ;
$result [ ‘counter_filesize’ ] += filesize ( $path ) ;
//unlink($path);
>
>
>
$result [ ‘path’ ] [ ‘dir’ ] [ ] = $dir ;
//rmdir($dir);
return $result ;
>
print_r ( remove_all_g ( $dir ) ) ;

function remove_all_sd ( $dir , $result = array ( ) )
<
if ( $paths = array_diff ( scandir ( $dir ) , array ( ‘..’ , ‘.’ ) ) )
<
foreach ( $paths as $path )
<
if ( is_dir ( $dir . ‘/’ . $path ) )
<
$result = remove_all_sd ( $dir . ‘/’ . $path , $result ) ;
>
else
<
$result [ ‘path’ ] [ ‘file’ ] [ ] = $dir . ‘/’ . $path ;
$result [ ‘counter_filesize’ ] += filesize ( $dir . ‘/’ . $path ) ;
// unlink($dir.’/’.$path);
>
>
>
$result [ ‘path’ ] [ ‘dir’ ] [ ] = $dir ;
// rmdir($dir);
return $result ;
>
print_r ( remove_all_sd ( $dir ) ) ;

Функция remove_all_g() для чтения содержимого директории применяется glob(), в remove_all_sd() — scandir(). При работе с 10 000 файлов, расположенных в 200 директориях различного уровня вложенности, функция remove_all_sd() отрабатывала, приблизительно на 20% быстрее.

Также, функция remove_all_g() не обнаруживает файлы, начинающиеся с точки, а если добавить ей эту функциональность — работать она будет еще медленнее.

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

Может кому пригодится, писал как-то для сайта. В $dirname передаёте путь к директории. В $result[] формируется массив из файлов с полным путём:
[code]
class UploadAnalize <

public function ListFilesDirectory($dirname) <
static $result = array();
$handle = opendir($dirname);

closedir($handle);
return $result;
>
>
[/code]

Мастер Йода рекомендует:  Без паники! Разбираемся с алгоритмами в 6 шагов
Добавить комментарий