Добрый день дорогой читатель Блога RS! Добро пожаловать на продолжение цикла статей посвященному разработки блога с нуля. Сегодня мы закончим создания менеджера файлов для нашей CMS. Первая часть поста, где я описывал логику работы нашего нового модуля Вы можете найти по этой ссылке. Поначалу может показаться, что предыдущий пост был пустой тратой времени, но это не так! После теоретической части будет легче понять практическую. В общем хватит лишних слов, приступим к делу
Первым делом хочу сказать, что если Вы на блоге впервые, то эта информация может показаться Вам совершенно не нужной. Этот пост, как впрочем и большинство других, является часть одного цикла статей, посвященному разработки блога с нуля. Если у Вас есть желание на практике научится создавать свой собственные проекты на php, то заходите по ссылке, что я Вам дал, и начинайте с первой части.
Так же, что бы не пропускать новые посты, подпишитесь по RSS через ридер или почту. Так же можете добавить меня в твиттере, я транслирую туда новые посты.
Теперь, что касается графики которая нам сегодня понадобится. Вот Вам архив, засуньте изображения из него в папку /admin/img/
Далее нам понадобится две папки в корне нашего движка.
Цели и порядок создания нашего менеджера уже есть в предыдущем посте, поэтому приступим к разработки
Открываем наш админский шаблон menu.html и добавляем в него новую кнопку
<table width="500px" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=add_content"><img src="img/add_content.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=all_content"><img src="img/all_content.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=all_menu"><img src="img/edd_menu.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=mfiles"><img src="img/mfiles.jpg" border="0px"></a></td>
<td width="100px" height="100px" valign="top" align="center"><a href="?page=contact"><img src="img/contact.jpg" border="0px"></a></td>
</tr>
</table>
Таким образом получаем вот такое меню
Создадим шаблон, с формой, назовем его mfiles.html и поместим в папку с админскими шаблонами
<div>Менеджер файлов</div>
<br/><br/>
<form action="index.php?page=mfiles" method="post" ENCTYPE="multipart/form-data" name="fimg">
<input size="50" name="userfile" type="file">
<br/><br/><input name="submit" type="submit" value="Добавить">
</form>
<br/><div>[_url]</div>
Тут обратите внимание на вот этот атрибут
ENCTYPE="multipart/form-data"
Этот атрибут обезопасит Вас от всяческих неприятностей, например на сервер не переместиться битый архив или не открывающееся изображение!
Создаем файл mfiles.php и помещаем его в модули нашей админ панели. Вот первая функция нашего нового модуля
function formfiles($linkFORfile)//Функция вывода формы
{
$sm_read = file("templates/mfiles.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его
$sm_read = str_replace("[_url]",$linkFORfile,$sm_read);//Меняем код слово на ссылку файла
return $sm_read;//Выводим с генерированный html код
}
Как Вы видите, тут ничего сложного нет, подключается шаблон и выводится результат.
Открываем наш шаблонизатор, index.php, и добавляем туда вот этот код
//МЕНЕДЖЕР ФАЙЛОВ
if($page == "mfiles")
{
include("moduls/mfiles.php");//подключаем модуль
//если сообщение с url не существует..
if(!isset($linkFORfile))$linkFORfile = "";//..то в отчет записываем пустоту
$txt = formfiles($linkFORfile);
}
//МЕНЕДЖЕР ФАЙЛОВ
В $linkFORfile хранится отчет о загрузки, то есть ссылка на файл, который мы загрузили. Если отчета нет, то есть мы еще не загружали файл, то мы в принудительном порядке записываем в отчет пустоту. Вот результат проделанной нами работы
В файле mfiles.php, в верху вставляем следующий код
//ДОБАВЛЕНИЕ ФАЙЛА
//Если форма была заполнена и отправлена то определяем переменную в которую запихнем файл
if(isset($_FILES['userfile']))$loadfile = $_FILES['userfile'];
if(isset($loadfile))//Если файл был отправлен
{
//Определяем тип файла
if($loadfile['type'] == "application/x-rar-compressed")$type = ".rar";
if($loadfile['type'] == "application/zip")$type = ".zip";
if($loadfile['type'] == "image/jpeg")$type = ".jpg";
if($loadfile['type'] == "image/gif")$type = ".gif";
if($loadfile['type'] == "image/png")$type = ".png";
if($loadfile['type'] == "image/bmp")$type = ".bmp";
//Определяем тип файла
if(isset($type))//Если тип определен и соответствует требованиям
{
//генерируем новое имя для файла
$name_f = date("His");//имя состоит из даты
$indifikator = mt_rand(1, 10000);//с генерированного числа от 1 до 10000
$name_f .= $indifikator;//склеиваем дату и с генерированное число
//генерируем новое имя для файла
//Определяем в какую папку загрузить файл
if($type == ".rar" OR $type == ".zip")//Если файл является архивом то..
{
$name_f = "download_".$name_f.$type;//...прикручиваем к названию файла приставку download и тип (download_имя.rar)
$folder = "../download/";//так же определяем имя папки куда загрузится файл
}
else//Если файл является изображением
{
$name_f = $name_f.$type;//...прикручиваем к названию файла тип (имя.jpg)
$folder = "../upload/";//так же определяем имя папки куда загрузится файл
}
copy($loadfile['tmp_name'], $folder.$name_f);//Копируем файл с новым именем в определенную папку
$linkFORfile = $folder.$name_f;//Составляем ссылку которую покажем на экране
}
else $linkFORfile = "Некорректный тип файла";//Сообщение о некорректности типа файла
}
//ДОБАВЛЕНИЕ ФАЙЛА
В коде все за комментировано, даже не знаю что добавить. Единственное, что я пожалуй сделаю, это еще раз поясню логику.
На этом логика окончена.
После внедрения этого кусочка кода, наш менеджер файлов, сможет сохранять необходимые нам файлы на сервере
Список будет иметь три режима. Режим будет определяться значением $scan, которая будет объявляться с помощью GET запроса. По умолчанию режим списка будет равен нулю, то есть закрыт.
Начнем с переделки нашего шаблона mfiles.html. Нам, в нем, необходимо создать таблицу, которая будет находится в блоковом теге див. У дива будет определен стиль display. Манипулировать этим стилем мы уже будем с помощью скрипта.
Вот переделанный шаблон
<div>Менеджер файлов</div>
<br/><br/>
<form action="index.php?page=mfiles" method="post" ENCTYPE="multipart/form-data" name="fimg">
<input size="50" name="userfile" type="file">
<br/><br/><input name="submit" type="submit" value="Добавить">
</form>
<br/><div>[_url]</div>
<br/><br/>
<a href="index.php?page=mfiles&scan=1">Список изображений</a> ::
<a href="index.php?page=mfiles&scan=2">Список архивов</a> ::
<a href="index.php?page=mfiles&scan=0">Закрыть список</a>
<br/><br/>
<div style="display:[_style];">
<form action="index.php?page=mfiles" method="post" name="del">
<table width="350px" cellpadding="0" cellspacing="0" border="0" align="center">
[_file]
<tr>
<td width="40px"><img src="[_img]" border="0px" width="40px" height="40px"></td>
<td align="center">[_link]</td>
<td align="center"><input type="checkbox" name="delF[[_del]]" value="[_delNAME]" /></td>
</tr>
[_file]
</table>
<br/><br/><input name="submit" type="submit" value="Удалить выбранные">
</form>
</div>
Я добавил ссылки на списки, так же саму таблицу. Давайте разберем код слова таблицы
Я все расписал очень подробно, надеюсь Вы разобрались
Разместим функцию, которую я приведу ниже, в файле mfiles.php в самом низу
function listFILE($typeSCAN,$sm_read)//Функция вывода списка
{
//Определяем какую папку открыл админ
if($typeSCAN == 1)$dir = '../upload';//папку с изображениями
if($typeSCAN == 2)$dir = '../download';//или папку с архивами
$data = opendir($dir); //сканируем файлы в папке
while (false !== ($one = readdir($data))) //собираем массив из результата сканирования
{
if($one != '.' AND $one != '..') //Удаляем точки
{
$files[] = $one;//формируем массив с именами файлов
}
}
closedir ($data);//закрываем папку
preg_match("/\[_file\](.*?)\[_file\]/s",$sm_read,$copy_sm);//вырезаем копию из шаблона (<tr>...</tr>)
for($i=0;isset($files[$i]);$i++)//генерируем строчки для таблицы
{
$copy_tp = $copy_sm[1];//делаем копию вырезанной части шаблона
//Определяем директорию из которой админу нужно вывести файлы
if($typeSCAN == 1)$img = $dir."/".$files[$i];//формируем пред просмотр ( пред просмотром в списке изображений являются сами изображения )
if($typeSCAN == 2)$img = "img/arh.jpg";//формируем пред просмотр ( пред просмотром в списке архивов является иконка архива )
//замена код слов
$copy_tp = str_replace("[_link]",$files[$i],$copy_tp);
$copy_tp = str_replace("[_img]",$img,$copy_tp);
$copy_tp = str_replace("[_del]",$i,$copy_tp);
$copy_tp = str_replace("[_delNAME]",$dir."/".$files[$i],$copy_tp);
//замена код слов
$result_sm .= $copy_tp;//Сохраняем с генерированную строчку таблицы в общую переменную
}
return $result_sm;//Выводим результат работы функции
}
Для старта функции нам понадобится знать режим открытия списка и копия шаблона. Я за комментировал каждую строчку в коде, я уверен Вы разберетесь
Вызов этой функции будет происходить из функции вывода формы. То есть нам сейчас необходимо переделать первую нашу функцию
function formfiles($linkFORfile,$typeSCAN)//Функция вывода формы
{
$sm_read = file("templates/mfiles.html");//...подключаем шаблон
$sm_read = implode("",$sm_read);//функция file() возвращаем массив, поэтому склеиваем его
//-------------НОВЫЙ КУСОЧЕК КОДА
if($typeSCAN != 0)//Определяем открыл ли админ какой-нить список
{
$result_sm = listFILE($typeSCAN,$sm_read);//запускаем функцию вывода списка
//Если результат функции пустота..
if($result_sm == "")$sm_read = str_replace("[_style]","none",$sm_read);//..то прячем всю таблицу с глаз долой
//Если же не результат функции НЕ пустота
else $sm_read = str_replace("[_style]","block",$sm_read);//..то показываем таблицу админу
}
else $sm_read = str_replace("[_style]","none",$sm_read);//Если админ НЕ открыл/закрыл список то прячем таблицу
$sm_read = preg_replace("/\[_file\].*?\[_file\]/s",$result_sm,$sm_read);//заменяем часть таблицы в шаблоне на с генерированный результат работы выше
//-------------НОВЫЙ КУСОЧЕК КОДА
$sm_read = str_replace("[_url]",$linkFORfile,$sm_read);//Меняем код слово на ссылку файла
return $sm_read;//Выводим с генерированный html код
}
Я выделил где новый кусочек кода, он за комментирован, так что разобраться в нем не составит труда. Там по сути происходит проверка результат функции вывода списка. Если пустота то стиль меняется на none если же нет, то стиль меняется на block.
Да и еще, обратите внимание на вот эту строчку
function formfiles($linkFORfile,$typeSCAN)//Функция вывода формы
Я добавил сюда еще одну стартовую переменную, стало быть нам необходимо будет переделать подключение в index.php. Но прежде чем переделывать подключение, нам необходимо объявить нашу $scan
В самом верху, файла mfiles.php, вставляем вот этот кусочек кода
//ОПРЕДЕЛЯЕМ КАКОЙ СПИСОК ОТКРЫЛ АДМИН
if(isset($_GET['scan']))$scan = $_GET['scan']; else $scan = 0;//определяем какой список открыл админ, и открыл ли его вообще
if(isset($scan))
{
if(!preg_match("/^[0-9]+$/",$scan) OR $scan > 2)//так как переменная scan должна быть числом, то..
{
header("location: index.php?page=mfiles");//..перенаправление
exit;//на страницу менеджера если это не так ($scan не есть число)
}
}
//ОПРЕДЕЛЯЕМ КАКОЙ СПИСОК ОТКРЫЛ АДМИН
Почему я отдельно остановился на этих строчка кода. Я по привычке воткнул проверку переменной. Для чего? Для того, что бы в эту переменную не пытались засунуть какой нить код, который мог бы повредить нашему движку. Суть защиты проста. Я знаю, что переменная должна содержать лишь 3 варианта значений, и при этом все три варианта являются числовым значением. Я просто проверяю переменную, является ли она числом. Если нет то скрипт останавливается. Вот и весь смысл
В скором будущем, я напишу пост, о защите блога, в котором мы будем подвергать такой проверки почти каждую переменную в нашем движке!
Кстати, в данном коде присутствует регулярное выражение, если вы не умеете ими пользоваться то почитайте вот этот пост
Заходим в файл index.php и редактируем наше подключение
//МЕНЕДЖЕР ФАЙЛОВ
if($page == "mfiles")
{
include("moduls/mfiles.php");//подключаем модуль
//если сообщение с url не сущесвует..
if(!isset($linkFORfile))$linkFORfile = "";//..то в отчет записываем пустоту
$txt = formfiles($linkFORfile,$scan);
}
//МЕНЕДЖЕР ФАЙЛОВ
Думаю тут без комментариев
Ну что ж. Теперь наш менеджер умеет открывать списки. Осталось реализовать удаление, и наш загрузчик будет готов!
Мы в шаблоне mfiles.html уже ввели форму для удаления. Чек боксы и соответствующая кнопка ведь присутствую ( скин выше тому доказательства ). Так что осталось написать обработчик, и дело в шляпе. Обработчик, который я сейчас выложу необходимо вклеить в файл mfiles.php между определением переменной scan и обработчиком добавления файла
//УДАЛЕНИЕ ФАЙЛА
if(isset($_POST['delF']))$delF = $_POST['delF'];//определяем запущен ли процесс удаление файлов
if(isset($delF))//если да
{
$allDEL = count($delF);//узнаем сколько файлов необходимо удалить
$nowDEL = 0;//считалка удаленных файлов
for($i=0;$nowDEL < $allDEL;$i++)
{
if(isset($delF[$i]))//если наткнулись на существующий элемент массива
{
unlink($delF[$i]);//удаляем файл который содержится в массиве
$nowDEL++;//подтверждаем что удалили еще один файл
}
}
header("location: index.php?page=mfiles");//Пере направление
exit;//на главную страницу менеджера
}
//УДАЛЕНИЕ ФАЙЛА
Все за комментировано, стало быть предельно ясно
Сегодня, я потратил около 6 часов на написание этого поста. При этом сам код я писал около 30 минут, и это при том что я понятие не имел как считывать файлы из директории. Не смотря на такой, как мне кажется, длинный пост мы сегодня реализовали менеджер файлов для нашего движка. С чем я Вас и поздравляю!
Если не считать некоторых "дырок" у движка, им уже можно пользоваться в полной мере. В скором времени мы эти явные "дырочки" прикроем, и напишем защиту от спама для некоторых форм, после чего этим скриптом можно будет пользоваться в всемирной паутине, что меня не может не радовать, ибо это первый мой проект, с очень (ИМХО) чистым кодом
Если Вам понравился мой блог, то подпишитесь на него через ридер, или же по почте.
Если есть какие вопросы/отзывы/комментарии, то пользуйтесь формой ниже
У этого поста есть продолжение.
Всего Вам наилучшего! У меня все!
Исходник |
С Неуважением Програмист
Я не програмМист, платными cms не пользуюсь из принципа. А тут код открытый. Будет конкурентоспособным, почему на этом не заработать денег?
p.s. БАГ. Неправильный код стирает набранное сообщение.. Это недостаток.
Если и буду писать модули дополнительно, то только для пополнения контента на блоге.
Warning: unlink(../download/.) [function.unlink]: Permission denied in Z:\home\localhost\www\blog\admin\modules\mfiles.php on line 64
Warning: Cannot modify header information - headers already sent by (output started at Z:\home\localhost\www\blog\admin\modules\mfiles.php:64) in Z:\home\localhost\www\blog\admin\modules\mfiles.php on line 68
if($one != '.' AND $one != '..') //Удаляем точки
{
$files[] = $one;//формируем массив с именами файлов
}
Ибо именно тут эти точки убираются
http://www.gcmsite.ru/?pg=art&id=php-header-mime-types
Попробуйте в файле mfiles.php написать вот так:
Fatal error: Call to undefined function mime_content_type() in Z:\home\test1.ru\www\admin\moduls\mfiles.php on line 40
Во-вторых скажите мне версию своего php. Очень странно, что у Вас отсутствует библиотека Fileinfo.
Единственное, что могу посоветовать (ну кроме определения почему библиотека Fileinfo не подключена, и подключить ее) это воспользоваться вот такой функцией:
Далее исправляем определение типа файла вот таким образом:
Перепроверил уже раз по 10:
1. не записывает архив (пишет не корректное имя файла),
2. не выводит строки (т.е. не формирует список файлов):
<div style="display:none;">
<form action="index.php?page=mfiles" method="post" name="del">
<table width="350px" cellpadding="0" cellspacing="0" border="0" align="center">
</table>
<br/><br/><input name="submit" type="submit" value="Удалить выбранные">
</form>
</div>
2. Менеджер теперь выводит файлы,
1. Но архивы так и незаписывает
А с добавлением функции вообще где-то всё тормозится и белый экран
Предупреждение: opendir(../upload,../upload) [function.opendir]: