-
Урок 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
17function 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
3function removefile ($path) {
if(unlink($path)) { return TRUE; }
else { return FALSE; } }Наиболее упрощенная функция, которая удаляет файл.В качестве аргумента передаем путь(имя) до файла.
1
2
3
4
5function 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&url='.$url.'">[создать папку]</a>
';
//Листинг папок
if(listing($url,1)) {
foreach(listing($url,1) as $f) {
echo '<a href="index.php?rename=1&url='.$url.'&fname='.$f.'">[переименовать]</a>';
echo '<a href="index.php?rmdir=1&url='.$url.'&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&url='.$url.'&fname='.$f.'">[переименовать]</a>';
echo '<a href="index.php?rmfile=1&url='.$url.'&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 'Ошибка
';}
}
}
?>Здесь сначала отображается форма, которая дает пользователю сменить имя, после ввода необходимых данных и нажатия на кнопку, запускается функция frename(). Если все завершилось без проблем, то происходит редирект на последнюю папку, в которой мы находились.
config.inc.php
Небольшой файл конфигурации.
1
2
3
4
5<!--?php</p-->
//Папка по умолчанию
$url="data";
?>Исходники
Заключение
Конечно данный скрипт не претендует на то чтобы Вы его использовали в своих проектах, т.к. здесь достаточно много различных уязвимостей, но он вполне подходит для поверхностного изучения необходимых функций. Если вам не терпиться можете запросто эксперементировать и добавлять необходимый функционал. Хочу сказать что в следующих уроках мы добавим несколько ключевых функций (копирование, перемещение, загрузка файла на сервер и др), поработаем над дизайном и защитой.
Будь как свежий огурец! Подпишись на RSS!51 Responses to “Урок 9. Файлы и папки в PHP. Пишем файловый менеджер.”
Страниц: « 6 5 4 3 [2] 1 » Show All
Страниц: « 6 5 4 3 [2] 1 » Show All
Leave a Reply





Ноябрь 7th, 2008 at 09:56
В своей практике ни разу не встречал файловых менеджеров (на unix-серверах) с поддержкой кириллицы.
Ноябрь 6th, 2008 at 21:03
А как быть с папками и файлами на кириллице?
Сентябрь 15th, 2008 at 15:58
2 Hide
Для соединения по ФТП в PHP существует набор функций. В вашем случае необходимо написать что то экзотическое =)
Сентябрь 14th, 2008 at 16:13
А можно сделать чтобы этот скрипт показывал папки другого сервера, соединяясь по фтп протоколу? И например я перехожу по папкам и щелкаю Добавить и адрес папки записывается в переменную. это тяжело реализовать?
Август 30th, 2008 at 22:17
Спасибо большое….
Август 30th, 2008 at 18:10
Игорь а чем вам не понравился вариант этот?
Август 30th, 2008 at 13:20
Уважаемый админ выложи свой готовый скриптик или пришли на мыло(igor_malyhin@mail.ru) я хотелбы посмотреть уже готовый чтоб лучше понять …….. структуру….
Август 25th, 2008 at 15:02
2 Avin
Я хотел бы чтобы Вы сами маленько подумали.Для более эффективно защиты необходимо проверять входящий путь при помощи регулярных выражений.Но маленько подскажу, чтобы человек не использовал как вы говорите ../../ , просто создайте условие:
Здесь при нахождении сочетания ../ , наш скрипт выдаст сообщение «Недопустимые символы в пути», и остановит выполнение дальнейших действий.
Август 25th, 2008 at 12:19
а что можно сделать чтобы пользователи не лезли куда не следует с помощью вставки ../../ Такжешь можно лихо начудить поудаляв чего не надо.
Август 21st, 2008 at 00:38
[...] фрагмент очень похож на тот, что мы использовали в файловом менеджере. Здесь помимо удаления файла из папки ещё необходимо [...]