Сайт компьютерных навыков

Спешный listing php. Самые основы. Как работает PHP. Ограничение глубины рекурсии

Если вы еще используете функцию opendir() для листинга папок в PHP, то прочтите как можно гораздо проще, и быстрее это сделать с помощью функции glob(). Glob это гораздо грамотное, вы убедитесь, посмотрев примеры использования glob() в php.

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

Введение

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

$dir = "/etc/php5/"; // Open a known directory, and proceed to read its contents if (is_dir($dir)) { if ($dh = opendir($dir)) { while (($file = readdir($dh)) !== false) { echo "filename: $file: filetype: " . filetype($dir . $file) . "\n"; } closedir($dh); } }

Если вы делали листинг папки с помощью opendir(), то пример выше вам знаком и нет смысла останавливаться на его разборе. Мы можем значительно сократить php код используя пример ниже:

$dir = "/etc/php5/*"; // Open a known directory, and proceed to read its contents foreach(glob($dir) as $file) { echo "filename: $file: filetype: " . filetype($file) . ""; }

Разве это не намного легче? Хотите узнать, как работает данный способ? Если да, то давайте разберемся с этим.

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

Первый аргумент glob() php

Первый аргумент функции glob поддерживает шаблон. Это означает, что вы можете ограничить область поиска несколькими каталогами или определенным типом файлов. Давайте предположим, что у вас есть сайт, который позволяет пользователям загружать изображения в их собственную папку в папке userimages. В этих папках еще папки с названиями HD и TN. HD - для высокого разрешения (полноразмерных фотографий), и TN для их превью. Давайте предположим, что вы хотите перебрать все превью пользователей в папке TN и вывести имена всех файлов. Это потребует php код значительного размера, если бы использовали open_dir(), однако с glob() в php это решается легко.

Foreach(glob("userImages/*/TN/*") as $image) { echo "Filename: " . $image . "
"; }

Этот скрипт пройдет по пути userimages/любая папка/TN/любой файл (папка) и вернет листинг папок соответствующих шаблону phpфункции glob().

Filename: userImages/username1/TN/test.jpg Filename: userImages/username1/TN/test3.jpg Filename: userImages/username1/TN/test5.png Filename: userImages/username2/TN/subfolder Filename: userImages/username2/TN/test2.jpg Filename: userImages/username2/TN/test4.gif Filename: userImages/username3/TN/styles.css

Мы можем указать более конкретно и включить расширение фала в шаблон glob():

Foreach(glob("userImages/*/TN/*.jpg") as $image) { echo "Filename: " . $image . "
"; }

Теперь результатом будут jpg файлы:

Filename: userImages/username1/TN/test.jpg Filename: userImages/username1/TN/test3.jpg Filename: userImages/username2/TN/test2.jpg

Но что же делать, если вы хотите запросить jpg и gif, исключая все остальные файлы? Или вывести только имена папок? В этом случае нам поможет второй аргумент.

Второй аргумент glob() php

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

GLOB_MARK : Добавляет слеш к каждому возвращаемому каталогу.

GLOB_NOSORT : Возвращает файлы так, как они появляются в каталоге (без сортировки).

GLOB_NOCHECK : Возвращает шаблон поиска в случае отсутствия совпадений с шаблоном.

GLOB_NOESCAPE : Обратные слеши не экранируют метасимволы.

GLOB_BRACE : Расширяет {а, Ь, с} для совпадения с "a", "b", или "c" (расширяет область поиска).

GLOB_ONLYDIR : Возвращение только записей папки, совпадающих с шаблоном.

GLOB_ERR : Остановка по ошибки чтения (например нечитаемые каталоги), по умолчанию ошибки игнорируются.

Как видите, наше требование может удовлетворить аргумент GLOB_BRACE:

Foreach(glob("userImages/*/TN/{*.jpg,*.gif}", GLOB_BRACE) as $image) { echo "Filename: " . $image . "
"; }

Этот пример вернет нам:

Filename: userImages/username1/TN/test.jpg Filename: userImages/username1/TN/test3.jpg Filename: userImages/username2/TN/test2.jpg Filename: userImages/username2/TN/test4.gif

Если мы хотим получить только имена подпапок, то используем GLOB_ONLYDIR:

Foreach(glob("userImages/*/TN/*", GLOB_ONLYDIR) as $image) { echo "Filename: " . $image . "
"; }

Filename: userImages/username2/TN/subfolder

Еще пример использования glob в PHP

Этот способ был доступен, начиная, с PHP 4.3, однако, как ни странно, им не пользуются часто. Раньше я не пользовался таким способом, теперь я всегда использую glob() во время загрузки плагинов в мою рабочую среду:

Foreach(glob("includes/plugins/*.php") as $plugin) { include_once($plugin); }

Вот и все! Надеюсь, вам понравилось. Дайте знать, если есть какие-то вопросы по поводу php glob!


Начиная писать программы для веба, многие начинающие программисты сталкиваются с такой ошибкой. Они рассматривают систему браузер-сервер, как обычное приложение. Интерактивное. Нажал кнопку - система среагировала. Провел мышкой - среагировала. Вся информация, которая доступна клиенту - доступна и программе, программа все время находится в памяти.
Так вот, в веб-программировании это не так! .
В момент, когда пользователь видит перед собой страницу и начинает совершать какие-то действия с ней, PHP уже завершил работу ! И пользователь взаимодействует не с PHP скриптом, а со своей страницей HTML, которую он получил в браузер. Результатом работы скрипта на PHP в большинстве случаев является обычный текст. Текст HTML страницы. Которая отдается браузеру и показывается им, как обычный HTML. Вы сами можете в этом убедиться, написав в скрипте
;
А потом просмотрев в браузере исходный текст полученной страницы. Никаких тегов PHP там нет! Только
Привет, Вася!
Потому, что PHP исполняется на сервере!

Сервер и браузер общаются, посылая друг другу запросы по особому протоколу - HTTP . Соединение может инициировать только браузер. Он посылает серверу запрос - показать такой-то файл. Сервер клиенту файл посылает.
Только так и происходит. Клиент запросил - сервер отдал. И забыл сразу о клиенте. Отсюда становится понятным ответ на вопрос, можно ли точно узнать, сколько юзеров сечас на сайте. Нельзя. потому, что "на сайте" нету ни одного. Они соединяются, запрашивают страницу, и отсоединяются. Не имеют постоянного cоединения с сервером, как, например, игроки в Кваку. Узнать можно только примерно, записывая время каждого соединения и выбирая записи за определенный промежуток времени.

Пример общения браузера с сервером:
Пользователь нажимает на ссылку, браузер посылает запрос серверу и ждет ответа:
Браузер -> PHP
PHP выполняет скрипт, отдает результат в браузер и завершает работу:
PHP -> браузер
Браузер отображает страницу, "просматривая" её на предмет ссылок, которые надо запросить у сервера (теги , и так далее) и посылает соответствующие запросы. Их можно увидеть, просматривая обмен заголовками, о чем речь будет чуть ниже:
Браузер -> сервер, Браузер -> сервер, Браузер -> сервер...
Пользователь заполняет форму и нажимает на кнопку:
Браузер -> PHP
PHP обрабатывает форму, записывает данные в базу и посылает браузеру заголовок
Location:
PHP -> браузер
Браузер, получив этот заголовок, запрашивает указанную страницу
Браузер -> PHP
PHP выполняет ее... и так далее.

Просмотр обмена HTTP заголовками
Я очень рекомендую попрактиковаться с HTTP заголовками, посмотреть, как ими обмениваются сервер и клиент.
Для этого есть множество разных способов. Если у вас стоит популярный download manager FlashGet, то можно использовать его. Так же заголовки показывает популярная программа Proxomitron, можно скачать какие-нибудь специальные утилиты.
Для IE можно предложить плагин http://blunck.se/iehttpheaders/iehttpheaders.html
Для браузера Mozilla есть удобный плагин http://livehttpheaders.mozdev.org/
Так же, существует много других утилит, легко находимых в сети по запросу HTTP sniffer.
Обязательно воспользуйтесь любым способом посмотреть HTTP заголовки, которыми обменивается браузер с сервером. Это очень хорошая практика, а так же проверка - что шлет твой скрипт. Удобно при отладке установки кук или проблемах с сессиями.
Примерное представление о пришедших заголовках можно также получить, воспользовавшись функцией getallheaders() . Но следует учитывать, что работает она только если PHP собран, как модуль.

ОЧЕНЬ ВАЖНОЕ ЗАМЕЧАНИЕ
Из того факта, что PHP исполняется на сервере, и посылает результат своей работы браузеру, следует один простой, но очень важный вывод. Что PHP в принципе НЕ МОЖЕТ отобразить в браузере ничего такого, что невозможно было бы сделать средствами html.
ПРЕЖДЕ, чем что-то писать на PHP - попробуйте это сделать чистым HTML.
"Нажатие на Энтер" не переводит строку? А в html вы не пробовали таким образом строки переводить? Не получилось? Какая досада. Прочитайте, как в html сделать перевод строки и приходите снова.

PHP в результате своей работы формирует не картинку с текстами, как вы ее видите на экране монитора! PHP формирует HTML код! И этот код ЗНАЧИТЕЛЬНО отличается от того изображения, которое вы видите на экране. Если у вас что-то не получается, то надо всегда смотреть именно ИСХОДНЫЙ код страницы, а не то, как вам ее рисует браузер. В браузере Internet Explorer исходный код можно посмотреть, выбрав в меню Вид - Просмотр HTML-кода.
Если у вас не работает яваскрипт, сформированный PHP скриптом, или html показывает не то, что вы хотите, то исправить эту проблему очень просто.
1. Сначала пишете нужный яваскрипт или html руками. Если у вас с этим проблемы - обратитесь в соотвествующий форум - по яваскрипту или html. PHP тут не при чём.
2. Сравниваете с тем, что получено из PHP
3. Вносите исправления в PHP скрипт, чтобы текст, отдаваемый им, не отличался от написанного руками.

Браузер не умеет показывать файлы, в которые напихан одновременно и html картинки. Браузер умеет показывать только известные ему типы данных. В частности, это ИЛИ html ИЛИ картинка. Но не вместе. Если картинка - то ОДНА. Несколько картинок подряд браузер показывать не умеет. Браузер умеет показывать HTML, в котором прописаны ССЫЛКИ на несколько картинок.
Пожалуйста, прежде, чем изучать PHP - изучите хотя бы основы HTML! Прежде, чем что-то требовать от PHP - попробуйте сделать это на html.

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

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

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

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

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

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

Назад Вперед

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

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

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

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

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

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

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

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

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

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

Пример 1:

Пример 2:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Немного о безопасности Можно сделать ограниченный доступ к панели управления (чтобы самому управлять из одного места) или «всемирный», чтобы из любого места можно было управлять.

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

  • В каждой внешней ссылке стоит такой атрибут rel="noreferrer"
  • Чтобы referer передавался только в пределах одного домена в head стоит тэг:
  • Все внешние ссылки идут через «очиститель referer»: http://nullrefer.com/?http://free.da...
Результат автоматизации 24 часа 7 дней в неделю все вновь появившиеся в ЦПО объявления досматриваются с интервалом в пару-тройку минут. В результате чего неугодные (по критериям, заданным пользователем) отправляются в раздел «заблокировано». Точно никогда не считал, но примерно из 100 заблокированных штук 90 - 95 заблокированы не зря. Из ста «чистых» по мнению ПО в среднем менее одного «плохого».

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

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

Стало меньше и воровства в виде неосознанных подписок даже без карты «МегаФона»!

А причём здесь карта «МегаФона»?

Похожие публикации