Reg.ru: домены и хостинг
Крупнейший регистратор и хостинг-провайдер в России.
Более 2 миллионов доменных имен на обслуживании.
Продвижение, почта для домена, решения для бизнеса.
Более 700 тыс. клиентов по всему миру уже сделали свой выбор.
Бесплатный Курс "Практика HTML5 и CSS3"
Освойте бесплатно пошаговый видеокурс
по основам адаптивной верстки
на HTML5 и CSS3 с полного нуля.
Фреймворк Bootstrap: быстрая адаптивная вёрстка
Пошаговый видеокурс по основам адаптивной верстки в фреймворке Bootstrap.
Научитесь верстать просто, быстро и качественно, используя мощный и практичный инструмент.
Верстайте на заказ и получайте деньги.
*Наведите курсор мыши для приостановки прокрутки.
Получение списка папок с помощью PHP
Список каталогов средствами PHP, или листинг директорий
Листингом директорий мы будем называть запрос общего вида, формирующий список всех, либо некоторых файлов и каталогов родительской директории - процесс похожий на работу индексной страницы, обеспечиваемой большинством веб-серверов, но с большим контролем над контентом и форматированием оного же.
Ещё одно преимущество данного скрипта - возможность выполнять определённые действия с файлами, используя PHP. В любом случае, первый шаг, который нам нужно сделать - это запрос к файловой системе - вернуть список файлов и каталогов.
Функции, представленные ниже, позволяют обеспечить извлечение имён файлов и других свойств из определённой директории или же пройтись по подкатегориям рекурсивно.
Замечание: в PHP5 есть функция scandir, которая "возвращает список файлов и каталогов, внутри директории, по заданному пути", однако она не выводит какую-либо дополнительную информацию о находящихся внутри директории файлах.
Листинг одной директории
Для начала, вот пример простой функции, которая возвращает список файлов, каталогов и их свойства, из одной директории (более продвинутые версии этой функции вы найдёте чуть ниже в данном уроке.)
<?php function getFileList($dir) { // массив, хранящий возвращаемое значение $retval = array(); // добавляет конечный слеш, если была возвращена пустота if(substr($dir, -1) != "/") $dir .= "/"; // указать путь до директории и прочитать список вложенных файлов $d = @dir($dir) or die("getFileList: Не удалось открыть каталог $dir для чтения"); while(false !== ($entry = $d->read())) { // пропустить скрытые файлы if($entry[0] == ".") continue; if(is_dir("$dir$entry")) { $retval[] = array( "name" => "$dir$entry/", "size" => 0, "lastmod" => filemtime("$dir$entry") ); } elseif(is_readable("$dir$entry")) { $retval[] = array( "name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry") ); } } $d->close(); return $retval; } ?>
Вы можете использовать эту функцию как ниже:
<?php // примеры сканирования текущей директории $dirlist = getFileList("."); $dirlist = getFileList("./"); // примеры сканирования директории, которая называется "images" $dirlist = getFileList("images"); $dirlist = getFileList("images/"); $dirlist = getFileList("./images"); $dirlist = getFileList("./images/"); ?>
Возвращаемое значение является ассоциативным массивом файлов, включающим в себя информацию о пути к файлу, размер и дату последней модификации, кроме случая, когда файл является директорией, в этом случае строка "(dir)" возникает вместо размера файла.
Пример 1:
<?php $dirlist = getFileList("images"); echo "<pre>",print_r($dirlist),"</pre>"; /* пример вывода Array ( [0] => Array ( [name] => images/background0.jpg [type] => image/jpeg [size] => 86920 [lastmod] => 1077461701 ) [1] => ... ) */ ?>
Пример 2:
<?php $dirlist = getFileList("./images"); echo "<pre>",print_r($dirlist),"</pre>"; /* пример вывода Array ( [0] => Array ( [name] => ./images/background0.jpg [type] => image/jpeg [size] => 86920 [lastmod] => 1077461701 ) [1] => ... ) */ ?>
Вывод списка файлов через HTML
Чтобы получить результаты вывода на странице в HTML, мы прокрутим возвращаемый массив через цикл
<?php // вывод результатов листинга в качестве HTML-таблицы echo "<table border=\"1\">\n"; echo "<tr><th>Name</th><th>Type</th><th>Size</th><th>Last Mod.</th></tr>\n"; foreach($dirlist as $file) { echo "<tr>\n"; echo "<td>{$file['name']}</td>\n"; echo "<td>{$file['type']}</td>\n"; echo "<td>{$file['size']}</td>\n"; echo "<td>",date('r', $file['lastmod']),"</td>\n"; echo "</tr>\n"; } echo "</table>\n\n"; ?>
Этот код довольно просто модифицировать, например:
- - вывести результаты листинга списком вместо таблицы;
- - сделать названия файлов активными ссылками;
- - заменить имена иконками на основании того, какой тип у файла;
- и т.д.
Например, для вывода только PNG-файлов, добавьте простое условие в цикл вывода:
<?php // вывод результатов листинга в качестве HTML-таблицы echo "<table border=\"1\">\n"; echo "<tr><th>Name</th><th>Type</th><th>Size</th><th>Last Mod.</th></tr>\n"; foreach($dirlist as $file) { //проверка на принадлежность файла к PNG if(!preg_match("/\.png$/", $file['name'])) continue; echo "<tr>\n"; echo "<td>{$file['name']}</td>\n"; echo "<td>{$file['type']}</td>\n"; echo "<td>{$file['size']}</td>\n"; echo "<td>",date('r', $file['lastmod']),"</td>\n"; echo "</tr>\n"; } echo "</table>\n\n"; ?>
В этом примере будут пропущены и скрыты все файлы, чьи имена заканчиваются на .png. Вы также можете применить дополнительные условия, основанные на типе файла, его размере или дате последнего изменения.
Если вы, например, хотите отобразить миниатюру, ссылкой на картинку большего размера, или даже видео, просто задайте этим 2-м файлам одинаковые имена и в скрипте выше используйте str_replace или похожую функцию, чтобы модифицировать содержимое ссылок.
Рекурсивный листинг директории
И раз уж мы зашли так далеко, здесь будут только незначительные изменения в функции вызова рекурсивного списка и субкатегорий. Добавляя второй параметр в функцию, мы сохраняем предыдущий функционал листинга одиночной директории.
<?php // Оригинальный код - Chirp Internet: www.chirp.com.au // Пожалуйста, укажите это в хедере, если будете использовать данный код function getFileList($dir, $recurse=false) { // массив, хранящий возвращаемое значение $retval = array(); // добавить конечный слеш, если его нет if(substr($dir, -1) != "/") $dir .= "/"; // указание директории и считывание списка файлов $d = @dir($dir) or die("getFileList: Не удалось открыть каталог $dir для чтения"); while(false !== ($entry = $d->read())) { // пропустить скрытые файлы if($entry[0] == ".") continue; if(is_dir("$dir$entry")) { $retval[] = array( "name" => "$dir$entry/", "size" => 0, "lastmod" => filemtime("$dir$entry") ); if($recurse && is_readable("$dir$entry/")) { $retval = array_merge($retval, getFileList("$dir$entry/", true)); } } elseif(is_readable("$dir$entry")) { $retval[] = array( "name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry") ); } } $d->close(); return $retval; } ?>
Чтобы новый функционал заработал, вам нужно ввести значение true (или 1) в качестве второго параметра.
<?php // одиночная директория $dirlist = getFileList("./"); // включая поддиректории $dirlist = getFileList("./", true); ?>
Перед рекурсингом скрипта проверьте, являются ли поддиректории читабельными а также ознакомьтесь с последним пунктом данного урока, дабы избежать ошибок доступа.
Как и раньше, возвращаемая величина - это массив, ассоциативный массивов. Фактически, единственное дополнение - это ещё одна дополнительная опция для рекурсивного листинга.
Ограничение глубины рекурсии
Этот финальный пример добавляет ещё одно свойство - способность к определению, как "глубоко" должна проходить рекурсия. Предыдущий код будет продолжать исследовать вложенные директории, до тех пор пока они не закончатся. Этот скрипт поможет установить ограничение, по количеству уровней вложенных директорий.
<?php // Оригинальный код - Chirp Internet: www.chirp.com.au // Пожалуйста, укажите это в хедере, если будете использовать данный код function getFileList($dir, $recurse=false, $depth=false) { // массив, хранящий возвращаемое значение $retval = array(); // добавить конечный слеш, если его нет if(substr($dir, -1) != "/") $dir .= "/"; // указание директории и считывание списка файлов $d = @dir($dir) or die("getFileList: Не удалось открыть каталог $dir для чтения"); while(false !== ($entry = $d->read())) { // пропустить скрытые файлы if($entry[0] == ".") continue; if(is_dir("$dir$entry")) { $retval[] = array( "name" => "$dir$entry/", "size" => 0, "lastmod" => filemtime("$dir$entry") ); if($recurse && is_readable("$dir$entry/")) { if($depth === false) { $retval = array_merge($retval, getFileList("$dir$entry/", true)); } elseif($depth > 0) { $retval = array_merge($retval, getFileList("$dir$entry/", true, $depth-1)); } } } elseif(is_readable("$dir$entry")) { $retval[] = array( "name" => "$dir$entry", "size" => filesize("$dir$entry"), "lastmod" => filemtime("$dir$entry") ); } } $d->close(); return $retval; } ?>
Как и раньше, мы добавили всего 1 новый параметр и пару строк кода. Если значение по умолчанию, отвечающее за глубину рекурсинга, не задано, то оно устанавливается в false. Это позволяет нам быть уверенными в том, что предыдущие особенности остаются и последующий код не "поломается" при изменении функции.
Другими словами, теперь мы можем вызвать функцию getFileList с одним, двумя или тремя параметрами.
<?php // одиночная директория $dirlist = getFileList("./"); // включая все вложенные категория $dirlist = getFileList("./", true); // включая 1 или 2 уровня глубины подкатегорий $dirlist = getFileList("./", true, 1); $dirlist = getFileList("./", true, 2); ?>
Это хороший пример того, как функция может эволюционировать спустя время, становясь при этом более управляемой.
Материал подготовил Денис Малышок специально для сайта CodeHarmony.ru
P.S. Хотите двигаться дальше в освоении PHP? Обратите внимание на премиум-уроки по различным аспектам сайтостроения, включая программирование на PHP, а также на бесплатный курс по созданию своей CMS-системы на PHP с нуля. Все это поможет вам быстрее и проще освоить этот мощный язык веб-разработки:
Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!
Смотрите также: