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

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

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

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

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

Перейти на сайт->

Бесплатный Курс "Практика HTML5 и CSS3"

Освойте бесплатно пошаговый видеокурс

по основам адаптивной верстки

на HTML5 и CSS3 с полного нуля.

Начать->

Фреймворк Bootstrap: быстрая адаптивная вёрстка

Пошаговый видеокурс по основам адаптивной верстки в фреймворке Bootstrap.

Научитесь верстать просто, быстро и качественно, используя мощный и практичный инструмент.

Верстайте на заказ и получайте деньги.

Получить в подарок->

Бесплатный курс "Сайт на WordPress"

Хотите освоить CMS WordPress?

Получите уроки по дизайну и верстке сайта на WordPress.

Научитесь работать с темами и нарезать макет.

Бесплатный видеокурс по рисованию дизайна сайта, его верстке и установке на CMS WordPress!

Получить в подарок->

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


Получение списка папок с помощью 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 с нуля. Все это поможет вам быстрее и проще освоить этот мощный язык веб-разработки:

Понравился материал и хотите отблагодарить?
Просто поделитесь с друзьями и коллегами!


Смотрите также:

PHP: Получение информации об объекте или классе, методах, свойствах и наследовании

PHP: Получение информации об объекте или классе, методах, свойствах и наследовании

CodeIgniter: жив или мертв?

CodeIgniter: жив или мертв?

Функции обратного вызова, анонимные функции и механизм замыканий

Функции обратного вызова, анонимные функции и механизм замыканий

Применение функции к каждому элементу массива

Применение функции к каждому элементу массива

Слияние массивов. Преобразование массива в строку

Слияние массивов. Преобразование массива в строку

Деструктор и копирование объектов с помощью метода __clone()

Деструктор и копирование объектов с помощью метода __clone()

Эволюция веб-разработчика или Почему фреймворк - это хорошо?

Эволюция веб-разработчика или Почему фреймворк - это хорошо?

Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.)

Магические методы в PHP или методы-перехватчики (сеттеры, геттеры и др.)

PHP: Удаление элементов массива

PHP: Удаление элементов массива

Ключевое слово final (завершенные классы и методы в PHP)

Ключевое слово final (завершенные классы и методы в PHP)

50 классных сервисов, программ и сайтов для веб-разработчиков

50 классных сервисов, программ и сайтов для веб-разработчиков

Наверх