Загрузка файлов на сервер.

26.12.2019
uploader_old

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

1. Первый способ, который будет рассмотрен – загрузка с помощью простой HTML формы с обработкой входящей информации средствами PHP.
Для реализации задачи будет использована простая форма с двумя полями “Описание” (ведь нужно же передать на сервер информацию о том что загружается) и “Выбор файла”…
Пропускаю код страницы содержащий заголовки,стили и кодировку – тут каждый сам лепит как хочет. Получается такая форма:


<form name="Upload" method="post" action="upload_plus.php" enctype="multipart/form-data" id="Form1">
<table width="399" height="203" border="0" bordercolor="#99CCFF" bgcolor="#E2E2E2">
<tr>
<TD>
<div align="center"><strong>ЗАГРУЗКА НОВОГО ФАЙЛА НА СЕРВЕР</strong></div>
</TD></tr>
</tr>
<td height="170"> Описание:
<input name="opis" type="text" id="opis" onChange="Submit.disabled=false;" onClick="Submit.disabled=false;"  size="42">
<strong><font size="2">Файл:</font></strong>
<input type="file" id="userfile[]"  size="35" name="userfile[]" >
<p align="left">
<input name="Submit" type="Submit" disabled="true" value="Сохранить запись " ></p>
</td>
<script type="text/javascript"><br />
function EnableBox(form, elem, evt){<br />
    var char = evt.keyCode;<br />
    if(char == 13){<br />
    form.submit();<br />
    return false;<br />
    }<br />
    return true;<br />
}<br />
</script></table>
</form>

Как Вы наверное заметили, в форме присутсвует табличная верстка, – просто мне так было удобно, можете сделать это DIV-ами.
Кроме того, наверняка обратили внимание на присутсвующий в коде формы javascript, – это обработчик нажатия клавиши Enter, которая в данном случае заменяет клик мышью по кнопке, если пользователю удобнее навигация с помощью клавиши Tab….
В объявлении формы присутсвует такая стока: method=”post” action=”upload_plus.php” enctype=”multipart/form-data“.
Данной строкой мы даем знать браузеру, что в форме передается содержимое разного типа, метод отправки скрипту-обработчику и собственно имя обработчика формы.
Обработчик же должен принять данные из формы и выполнить загрузку файла на сервер. Код обработчика содержит следующие параметры (я их так назвал): $uploaddir – полный путь к каталогу хранения файлов на сервере
$updir – имя целевого каталога
$allowed – разрешенные к загрузке типы файлов
$max_size – максимально разшененный размер загружаемого файла
$text – полученное из формы текстовое значение
В коде приведенном ниже, Вы наверняка обратите внимание на переменную “Х”, которая в ходе проверки будет учеличиваться на еденицу ($x=$x+1;), – это сделано для того, чтобы исключить дублирование имен файлов.
Таким образом, в процессе загрузки, принимающий php-скрипт заменяет имя загружаемого файла на цифровое значение.
uploader_old2
Файлы сохраняются под именами вида “1.doc”,”2.doc” (или другого расширения), что позволяет дать каждому файлу уникальное имя.
После загрузки скрипт сообщает об успешной (или нет) загрузке файла и URL до файла на сервере. Код загрузчика:

$uploaddir = 'E:/site/files/';
$updir = '/files/';
$allowed   = array('doc','xls','zip','pdf','rar','jpg','bmp','gif','chm','exe');// разрешенные типы файлов
$max_size  = 1024*300*1024; // максимальный размер файла
$x=0;
$text = $_REQUEST["opis"];
if ($text == "") {
echo 'НЕ ВВЕДЕНО ОПИСАНИЕ ЗАГРУЗКИ!'.'
'."\n";
$err_2=1;
} else { $err_2=0 ;}
if ($err_2==0){
# Процесс выполнения загрузки файла и проверка на ошибки
if (isset($_FILES['userfile'])) {
foreach ($_FILES['userfile']['error'] as $i => $error) {
if ($_FILES['userfile']['size'][$i] == 0) { echo 'НЕ ВЫБРАН ФАЙЛ ДЛЯ ЗАГРУЗКИ!'.'
'."\n";}
if ($error == 0 && $_FILES['userfile']['size'][$i] <= $max_size) { 
      $file_ext  = pathinfo($_FILES['userfile']['name'][$i],PATHINFO_EXTENSION); 
      $file_name = basename($_FILES['userfile']['name'][$i],'.'.$file_ext);
	    if (in_array(strtolower($file_ext),$allowed)) { 
       		$x=$x+1;
		$new_base = $x.'.'.$file_ext; 
      while (file_exists($uploaddir.$new_base)) {
		$x=$x+1;
		$new_base = $x.'.'.$file_ext; 
				  }
$endurl='http://'.$_SERVER['SERVER_NAME'].$updir.$new_base;
         if (move_uploaded_file($_FILES['userfile']['tmp_name'][$i],$uploaddir.$new_base)) { 
          chmod($uploaddir.$new_base, 0644); 
         echo 'Загружен файл: '.$_FILES['userfile']['name'][$i].'
'."\n";
echo 'Описание: '.$text.'
'."\n";
}}else{echo 'Загрузка файлов этого типа не разрешена или файл слишком большого размера.'.'
'."\n";}
}}}}

На этом завершим описание первого способа.

2. Второй способ, который будет рассмотрен – загрузка с помощью формы, основой обработки которой будет плагин uploadify JQuery, с flash элементом в структуре формы.
Этот спопоб намного сложнее приведенного выше, но и выглядит приятнее и возможностей больше.
Следует сказать, что 2-ой способ приведу ASIS, т.е. так как я его использовал.
Здесь присутствует связка с базой данных, ajax, комбобокс, проверка целостности файла по хэшу MD5 и проверка перед запись в базу данных по структуре информации переданной из формы (это может быть как загрузка файла, так и запись в виде ссылки). На страницы целевого сайта выводится вся необходимая информация, но об этом сейчас не будем, – запросы к БД Вы писать, надеюсь, умеете 🙂
И так. Код формы приведу урезано, – по необходимости создадите свою структуру, но смысл будет ясен.

<h3>Загрузка информации на сайт</h3>
<form>
<div id="queue"></div>
<strong>Раздел:</strong>
<select name="razd"  id="list" style="width: 293px;"onchange="idx=this.selectedIndex;razdel();">
<option value=0 style="color:red;">Выберите раздел !</font></option>
<option value=1>Фотографии</option>
<option value=2>Документы</option>
<option value=3>Ссылки</option>
</select>
<strong>Описание: </strong>
<input name="subj" type="text" id="subj"  size="43">
<strong>Ссылка :</strong>
<input type="text" size="43" id="url"  value="" disabled>
<input  name="file_upload" type="file" id="file_upload"   multiple="false" >
</form>

Выбор раздела сразу же обрабатывается скриптом, который возвращает в переменную value выбранного пункста.
Описание – текстовое поле, для ввода комментария.
Ссылка – поле для указания URL , если создается запись с вложением ссылки на какой-то ресурс.
Обратите внимание на поле для файла. Оно вроде бы есть в коде, но с использованием плагина uploadify оно не выводится, пока не выбран файл. Выбранный файл отобразится только после нажатия кнопки “Выберите файл” и собственно его выбора.
Здесь есть небольшой нюанс – кодом который будет ниже, предусмотрен “костыль” – файлы в окне выбора не будут отображаться пока не выбран раздел для размешения. Своего рода “защита от дурака”.
Максимальный размер файла заданный в приведенном выше коде, должен быть не более разрешенного в настройках Web-сервера.
Для придания уникальности шифрования файла md5 используем “соль”, роль которой выполнит текушее время.
Теперь, после формы, на странице необходимо подключить скрипт загрузки.

<script type="text/javascript"><br />
<?php $timestamp = time();?><br />
$(function() {<br />
$('#file_upload').uploadify({<br />
'formData'     : {<br />
	'method'   : 'post',<br />
	'dataType': "text",<br />
	'timestamp' : '<?php echo $timestamp;?>',<br />
	'token'     : '<?php echo md5('unique_salt' . $timestamp);?>'<br />
		},<br />
	'auto'     : false, // запретить автозагрузку файла на сервер (ждем команды)<br />
	'fileTypeExts' : 'Не выбран раздел' ,<br />
	'buttonText' : 'Выберите файл',<br />
	 'swf'      : 'uploadify.swf',<br />
	 'uploader' : 'uploadify.php',<br />
               	'checkExisting' : 'check-exists.php',<br />
	'removeCompleted' : false,<br />
	 'multi'     : false,<br />
	 'uploadLimit' : 1,<br />
	'onUploadComplete' : function(data) {<br />
                  $('#file_upload').uploadify('settings','uploadLimit','0');<br />
	$('#outfile').empty();<br />
	$('#outfile').text('Запись данных выполнена!');<br />
				}<br />
           });<br />
		});<br />
</script>

Не буду расписывать все параметры uploadify, все доступно в интернете. Форма описана, скрипт обработки приведен. Далее выведем кнопки:

<button id="ok" class="b1"  onclick="javascript: a();">Выполнить загрузку</button>
<button id="new" class="b1"  onclick="javascript:b();">Новая загрузка</button>
<div id="outfile" style="font-weight: bold;"></div>

Обратили внимание на функции javascript в обработчиках кнопок? Их описания еще нет. Распишем. Первое и важное здесь – необходимо подсключить jquery и класс uploadify, поэтому в head страницы обязательно нужно их подключить.
Подключаем:

<head>

<title>Загрузка информации на сайт</title>
<script src="jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="jquery.uploadify.min.js" type="text/javascript"></script>
 	 	<link rel="stylesheet" type="text/css" href="uploadify.css">

Туда же нужно включить и скрипты обработки формы (выбора раздела и кликов по кнопкам)

<script type="text/javascript"><br />
 var idx=0;<br />
function a() {<br />
opisan=$('#subj').val();<br />
if(idx>0 && opisan !=""){<br />
	if(idx<3){ // потому что 3 пункт у нас не является загрузкой файла
	$('#file_upload').uploadify('settings', 'formData', {'subj' : $('#subj').val() });
	$('#file_upload').uploadify('settings', 'formData', {'id' : idx});
	$('#file_upload').uploadify('upload');
	$('#file_upload').uploadify('disable', true);
	}
if(idx>2){ // отправляем обработчику только текстовую информацию<br />
$('#file_upload').uploadify('disable', true);<br />
$.get("uploadify.php", {<br />
	id:idx,<br />
	subj: $('#subj').val(),<br />
	link: $('#url').val()<br />
		}<br />
	);<br />
   }<br />
document.getElementById('ok').disabled=true;<br />
document.getElementById('new').disabled = false;<br />
}else{<br />
alert('Введены не все данные !');}<br />
}<br />
function b() { //новая загрузка, очистка формы и переменных<br />
$('#file_upload').uploadify('cancel');<br />
if(idx<5){
	$('#file_upload').uploadify('disable', false)
		};
document.getElementById('new').disabled=true;
document.getElementById('ok').disabled = false;
$('#outfile').empty();
$('#subj').val(''); 
$('#url').val('');
}
function razdel() { //меняем настройки uploadify от типа загрузки
if(idx==0){
$('#file_upload').uploadify('settings','fileTypeExts','*.netfaila;');
$('#file_upload').uploadify('settings','fileTypeDesc','Не выбран раздел');
$('#file_upload').uploadify('disable', true);
document.getElementById('url').disabled = true;
	}
if(idx==1){
$('#file_upload').uploadify('settings','fileTypeExts','*.jpg');
$('#file_upload').uploadify('settings','fileTypeDesc','Изображения и фотографии');
$('#file_upload').uploadify('disable', false);
document.getElementById('url').disabled = true;
	}
 if(idx==2){
$('#file_upload').uploadify('settings','fileTypeExts','*.jpg; *.jpeg; *.docx; *.doc; *.xlsx; *.xls; *.pdf;  *.ppsx;  *.pptx;  *.ppt;  *.zip;  *.7z;  *.rar');
$('#file_upload').uploadify('settings','fileTypeDesc','Документы');
$('#file_upload').uploadify('disable', false);
document.getElementById('url').disabled = true;
}
if(idx==3){
$('#file_upload').uploadify('disable', true);
document.getElementById('url').disabled = false;
	}
}
</script>

На этом формирование страницы для выбора загрузки 2-м способом завершено. CSS и разметка страницы тут не учитывается.
Теперь приступим к обработке информации от формы.
Для этого служат указанные в параметрах выше описанной страницы скрипты : uploadify.php и check-exists.php.
Файл check-exists.php служит для проверки путей и наличия в целевом каталоге такого же имени файла. В прочем проверку имени можно и не делать, поскольку, как я Вам покажу дальше, имя файла будет генерироваться по хэшу md5 текушего времени в формате microtime, но таков уж uploadify – требует возврата значения об ошибке…
Приведу код моего php-скрипта как есть… Разобраться не трудно.

$data= date("Y.m.d");
$dbhost='localhost';
$dbuser='user;
$dbpassword='pass';
$database='dbname';
$db = mysql_connect($dbhost, $dbuser, $dbpassword)
or die("Ошибка соединения: " . mysql_error());
mysql_select_db($database) or die("Ошибка соединения с базой данных");
mysql_query("SET NAMES utf8");
$razd=$_POST['id'];
if($razd == ""){
$razd=$_GET['id'];
}
if ($razd<3){
$subj=$_POST['subj'];
$targetFolder = '/files/'; // каталог назначения загруженных файлов
$verifyToken = md5('unique_salt' . $_POST['timestamp']);
if (!empty($_FILES) && $_POST['token'] == $verifyToken) {
$tempFile = $_FILES['Filedata']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
// проверка типа файла
$fileTypes = array('jpg','jpeg','docx','doc','xlsx','xls','pdf','ppsx','pptx','ppt','zip','7z','rar','avi','mpg','mpeg','exe','msi'); // разрешенные расширения 
$fileParts = pathinfo($_FILES['Filedata']['name']);
$file_ext  = $fileParts['extension'] ; //расширение загружаемого файла
$filename = md5(microtime()); //генерация нового имени
$new_file = $filename.'.'.$file_ext; 
$targetFile = rtrim($targetPath,'/') . '/' . $new_file; //переименованный файл подготовлен
if (in_array($fileParts['extension'],$fileTypes)) {
move_uploaded_file($tempFile,$targetFile);      // если тип файла разрешен - заливаем
echo '1'; // ключ выполненной операции
$endurl='http://'.$_SERVER['SERVER_NAME'].$targetFolder.$new_file; //сформировал URL загруженного файла для браузера
//Теперь можно делать запись в БД
$ins="insert into content(razdel,subject,link,data) values('$razd','$subj','$endurl','$data')"; 
mysql_query($ins);
}}
}else{
//запись без загрузки файла
$url=$_GET['link'];
$subj=$_GET['subj'];
$ins="insert into content(razdel,subject,link,data) values('$razd','$subj','$url','$data')"; 
mysql_query($ins);
}

Вот и всё! Удачных реализаций!
И не забудьте поставить LIKE кнопкой соц.сети справа от записи.

Оставить комментарий