программирование на PHP
Bullet (black) Email иконка RSS иконка
  • Урок 9. Файлы и папки в PHP. Пишем файловый менеджер.

    Июль 29th, 2008 Александр 51 Комментариев

    Введение

    Рано или поздно каждому новичку придется столкнуться с проблемой создания приложения, функционал которого должен позволять просматривать папки и файлы на сервере. Т.е необходимо реализовать файловый менеджер. Применяется данное приложение  в административных модулях и на хостингах, для управления файлами через веб-браузер. Конечно в сети есть множество навороченных скриптов, с применением AJAX или javascript’а, функциональность которых практически ничем не отличается от десктопных, но цель нашего урока – ознакомиться с элементарными функциями для работы с папками и файлами.

    Детали

    Рассмотрим основные функции, с которыми мы сегодня ознакомимся:

    • Чтение и вывод содержимого директории;
    • Создание папки;
    • Удаление папки и файлов;
    • Переименование папок и файлов;
    • Получение размера файлов.

    Самая простая задача, которая сейчас стоит перед нами – это научиться считывать содержимое директории на сервере, группировать данные(файла, папки) и выводить их в браузер. Данные скрипты можно тестировать и на локальном сервере, для этого создайте в папке www папку dir, в ней будут наши скрипты. В папке dir создайте папку data. Папка data будет нашей рабочей директорией, в ней необходимо создать несколько любых папок и накидать файлы разных форматов для тестирования.А теперь приступим к программированию. Наш файловый менеджер будет состоять из нескольких файлов:

    • index.php – главная страница, с основными логическими операциями;
    • functions.inc.php – файл будет содержать все необходимые функции для работы;
    • config.inc.php – файл конфигурации.

    Чтение директории

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    //Указываем рабочую папку по умолчанию
    $url = "data";
    //Проверяем, является ли директорией
    if (is_dir($url)) {
    //Проверяем, была ли открыта директория
    if ($dir = opendir($url)) {
    //Сканируем директорию
    while (false !== ($file = readdir($dir))){
    //Убираем лишние элементы
    if ($file != "." && $file != "..") {
    //Выводим спиоск в браузер
    echo $file."
    "
    ;
    }
    }
    //Закрываем директорию
    closedir($dir);
    }
    }

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

    functions.inc.php

    Создаем файл functions.inc.php и помещаем туда следующий список функций:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    //Листинг папок
    function listing ($url,$mode) {
    //Проверяем, является ли директорией
    if (is_dir($url)) {
    //Проверяем, была ли открыта директория
    if ($dir = opendir($url)) {
    //Сканируем директорию
    while (false !== ($file = readdir($dir))) {
    //Убираем лишние элементы
    if ($file != "." && $file != "..") {

    //Если папка, то записываем в массив $folders
    if(is_dir($url."/".$file)) {
    $folders[] = $file;
    }
    //Если файл, то пишем в массив $files
    else {$files[] = $file;}
    }
    }
    }
    //Закрываем директорию
    closedir($dir);
    }
    //Если режим =1 то возвращаем массив с папками
    if($mode == 1) {return $folders;}
    //Если режим =0 то возвращаем массив с файлами
    if($mode == 0) {return $files;}
    }

    У данной функции в качестве аргументов передаются путь и режим. Если $mode = 1,то функция возвращает массив с папками, если 0, то массив с файлами. Продолжим.

    1
    2
    3
    4
    5
    6
    7
    //Функция создания папки
    function makedir ($url){
    //Вырезаем пробелы и хтмл-тэги
    $url = trim(htmlspecialchars($url));
    //Если папка создается возвращаем TRUE
    if(@mkdir($url)){return TRUE;}
    else{return FALSE;} }

    Данная функция будет создавать папку. Как он будет работать? Для этого существует замечательная функция – mkdir(). Все остальное дело прямых рук=)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    //Функция переименования
    function frename ($url,$oldname,$nname){
    $nname = trim(htmlspecialchars($nname));
    $oldname = trim(htmlspecialchars($oldname));
    $url = trim(htmlspecialchars($url));
    if(@rename($url."/".$oldname,$url."/".$nname))

    {return TRUE; }
    else {return FALSE; } }

    Достаточно простая функция, аргументами которой являются путь, имя старого файла/папки и имя нового файла/папки.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function removedir ($directory) {
    $dir = opendir($directory);
    while(($file = readdir($dir)))
    {
    if ( is_file ($directory."/".$file))
    {
    unlink ($directory."/".$file);
    }
    else if ( is_dir ($directory."/".$file) &&
    ($file != ".") && ($file != ".."))
    {
    removedir ($directory."/".$file);
    }
    }
    closedir ($dir);
    rmdir ($directory);
    return TRUE;  }

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

    1
    2
    3
    function removefile ($path) {
    if(unlink($path)) { return TRUE; }
    else {    return FALSE; } }

    Наиболее упрощенная функция, которая удаляет файл.В качестве аргумента передаем путь(имя) до файла.

    1
    2
    3
    4
    5
    function updir( $path ){
    $last = strrchr( $path, "/" );
    $n1 = strlen( $last );
    $n2 = strlen( $path );
    return substr( $path, 0, $n2-$n1 ); }

    А вот это очень полезная функция, которая позволит получать имя предыдущей папки.

    1
    2
    3
    4
    5
    //Получаем размер файла
    function fsize($path) {
    return substr(filesize($path)/1024, 0, 4);
    }
    ?>

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

    index.php

    Листинг файлов и папок

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <!--?php<br /--> //Подключаем файл конфигурации
    include("config.inc.php");
    //Подключаем файл с функциями
    include("functions.inc.php");

    //Указываем рабочую папку по умолчанию
    if($_GET['url']) {$url = $_GET['url']; }

    //Шапка
    echo 'Текущая директория:  '.$url.'
    '
    ;

    echo '<a href=".">[корень]</a> ';
    echo '<a href="index.php?url='.updir($url).'">[вверх]</a> ';
    echo '<a href="index.php?mkdir=1&amp;url='.$url.'">[создать папку]</a>

    '
    ;

    //Листинг папок
    if(listing($url,1)) {
    foreach(listing($url,1) as $f) {
    echo '<a href="index.php?rename=1&amp;url='.$url.'&amp;fname='.$f.'">[переименовать]</a>';
    echo '<a href="index.php?rmdir=1&amp;url='.$url.'&amp;fname='.$f.'">[удалить]</a> ';
    echo '<img src="img/dir.gif" alt="" /><a href="index.php?url='.$url.">'.$f.'</a>
    ';
    }}
    //Листинг файлов
    if(listing($url,0)) {
    foreach(listing($url,0) as $f) {
    echo '<a href="
    index.php?rename=1&amp;url='.$url.'&amp;fname='.$f.'">[переименовать]</a>';
    echo '<a href="
    index.php?rmfile=1&amp;url='.$url.'&amp;fname='.$f.'">[удалить]</a> ';
    echo '<img src="
    img/'.strtolower(substr($f,-3)).'.gif" alt="" />'.$f.' - '.fsize($url).'
    ';
    }}

    Этот фрагмент можно условно поделить на 3 части:

    • Первая это «шапка» – меню, которое статично и отображается во всех разделах одинаково. Сама «шапка» содержит 3 ссылки: корень, вверх и новая папка.
    • Листинг папок. Здесь все просто, при помощи функции foreach производим вывод данных из массива. Рядом с каждой папкой имеются ссылки: переименовать и удалить.
    • Листинг файлов. Здесь тоже просходит вывод из массива $files, поэтому рядом с каждым файлом имеются ссылки: переименовать и удалить. Также рядом с каждым файлом выводиться его размер.

    Чтобы было нагляднее, я сделал отображение иконки соответсвующей типу файла.

    Отдельное слово про навигацию. Здесь все достаточно просто, если скрипту не передаются никакие параметры, то папка по умолчанию будет data, если же мы перешли в другую папку, то $url = $_GET['url'], т.е. тот путь который мы передали по ссылке.

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

    Создание папок

    Следующий скрипт позволяет добавлять папки.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    //Создание папок
    if($_GET['mkdir'])
    {
    if(!$_POST['add']) {
    echo '

    <form action="?mkdir=1" method="post">'
    ;
    echo 'Имя новой папки:
    '
    ;
    echo '
    <input name="ndir" type="text" />'
    ;
    echo '
    <input name="url" type="hidden" value="'
    .$_GET['url'].'" />
    '
    ;
    echo '
    <input name="add" type="submit" value="создать" /></form>'
    ; }
    else {
    if(makedir($_POST['url']."/".$_POST['ndir'])!== FALSE) {
    header("location:index.php?url=".$_POST['url']);     }
    else {echo 'Ошибка
    '
    ;}
    }}

    Для того чтобы он заработал, скрипту index.php необходимо передать переменную $_GET['mkdir'] . Данное действие реализовано ссылкой в шапке. Обязательно по ссылке передаем текущую рабочую директорию в переменной $url. После того как мы нажали на ссылку, снизу будет отображена форма, в которой необходимо ввести имя новой папки. После нажатия кнопки сработает функция makedir().

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

    Удаление папок

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

    1
    2
    3
    4
    5
    //Удаление папок
    if($_GET['rmdir']){
    if(removedir($_GET['url']."/".$_GET['fname']) !== FALSE) {
    header("location:index.php?url=".$_GET['url']);
    } }

    Для того чтобы это условие выпонилось, необходимо файлу index.php передать нужные параметры, т.к. при листинге файлов и папок выводятся сервисные ссылки, которые содержат необходимые параметры, то реализовать это будет несложно. Здесь $rmdir=1 означает то, что будет выполнено условие  на удаление – if($_GET['rmdir']){} , а необходимые параметры передаем функции removedir() через GET параметры , при успешной завершений которой, происходит редирект на последнюю рабочую папку.

    Удаление файлов

    Идентичный скрипт, который отличается только исполняемой функцией.

    1
    2
    3
    4
    //Удаление файлов
    if($_GET['rmfile']){
    if(removefile($_GET['url']."/".$_GET['fname']) !== FALSE) {
    header("location:index.php?url=".$_GET['url']);

    Работа этого скрипта полностью повторяет принцип удаления папки.

    Переименование папок и файлов

    Чтобы переименовать файл, нам необходимо знать путь до него, его старое имя и естественно новое имя. Следующий фрагмент кода позволяет переименовывать файлы и папки. Не забывайте что при листинге напротив каждого файла и папки есть ссылка, которая содержит необходимые параметры (путь,имя файла).

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    //Переименование папок и файлов
    if($_GET['rename'])
    {
    if(!$_POST['rename']) {
    echo '

    <form action="?rename=1" method="post">'
    ;
    echo 'Новое имя:
    '
    ;
    echo '
    <input name="nname" type="text" value="'
    .$_GET['fname'].'" />';
    echo '
    <input name="url" type="hidden" value="'
    .$_GET['url'].'" />
    '
    ;
    echo '
    <input name="oldname" type="hidden" value="'
    .$_GET['fname'].'" />';
    echo '
    <input name="rename" type="submit" value="ok" /></form>'
    ; }
    else {
    if(frename($_POST['url'],$_POST['oldname'],$_POST['nname'])!== FALSE) {
    header("location:index.php?url=".$_POST['url']);     }
    else {echo 'Ошибка
    '
    ;}
    }
    }
    ?&gt;

    Здесь сначала отображается форма, которая дает пользователю сменить имя, после ввода необходимых данных и нажатия на кнопку, запускается функция frename(). Если все завершилось без проблем, то происходит редирект на последнюю папку, в которой мы находились.

    config.inc.php

    Небольшой файл конфигурации.

    1
    2
    3
    4
    5
    <!--?php</p-->

    //Папка по умолчанию
    $url="data";
    ?&gt;

    Исходники

    simplefmanager.zip

    Заключение

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

    Будь как свежий огурец! Подпишись на RSS!

    51 Responses to “Урок 9. Файлы и папки в PHP. Пишем файловый менеджер.”

    Страниц: « 6 5 4 3 [2] 1 » Show All

    1. 20
      АлександрNo Gravatar Says:

      В своей практике ни разу не встречал файловых менеджеров (на unix-серверах) с поддержкой кириллицы.

    2. 19
      BuHTNo Gravatar Says:

      А как быть с папками и файлами на кириллице?

    3. 18
      АлександрNo Gravatar Says:

      2 Hide
      Для соединения по ФТП в PHP существует набор функций. В вашем случае необходимо написать что то экзотическое =)

    4. 17
      HideNo Gravatar Says:

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

    5. 16
      ИгорьNo Gravatar Says:

      Спасибо большое….

    6. 15
      АлександрNo Gravatar Says:

      Игорь а чем вам не понравился вариант этот?

    7. 14
      ИгорьNo Gravatar Says:

      Уважаемый админ выложи свой готовый скриптик или пришли на мыло(igor_malyhin@mail.ru) я хотелбы посмотреть уже готовый чтоб лучше понять …….. структуру….

    8. 13
      АлександрNo Gravatar Says:

      2 Avin
      Я хотел бы чтобы Вы сами маленько подумали.Для более эффективно защиты необходимо проверять входящий путь при помощи регулярных выражений.Но маленько подскажу, чтобы человек не использовал как вы говорите ../../ , просто создайте условие:

      1
      if(ereg("^([../])",$url)) { die("Недопустимые символы в пути");}

      Здесь при нахождении сочетания ../ , наш скрипт выдаст сообщение «Недопустимые символы в пути», и остановит выполнение дальнейших действий.

    9. 12
      avinNo Gravatar Says:

      а что можно сделать чтобы пользователи не лезли куда не следует с помощью вставки ../../ Такжешь можно лихо начудить поудаляв чего не надо.

    10. 11
      Урок 13.Создание фотогалереи на сайте. Менеджер изображений. | Freshcoder.ru - уроки PHP Says:

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

    Страниц: « 6 5 4 3 [2] 1 » Show All

    Leave a Reply


freshcoder.ru © 2008 • При использовании материалов активная ссылка на сайт обязательна.