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

А этом уроке я покажу вам пример интеграции замечательного плагина Dropzone.js с вашим сайтом на php для загрузки файлов на сервер буквально в несколько строк кода.

Dropzone.JS это замечательная опенсурс библиотека написанная на ванильном JS предоставляющая вам интерфес для загрузки файлов drag and drop с предварительным просмотром файлов.

Для начала скачайте свежую версию библиотеки и её стили:

https://raw.githubusercontent.com/enyo/dropzone/master/dist/dropzone.js

https://raw.githubusercontent.com/enyo/dropzone/master/dist/dropzone.css

Затем создайте папку uploads и файлы index.php и upload.php

В качестве файла index php может выступать та часть вашего кода, которая содержит форму добавления материалов на сайт. В моём примере я создам чистую страницу с минимальной разметкой и подключеной библиотекой и стилями Dropzone.js:

<html>
<head>   
 
    <link href="css/dropzone.css" type="text/css" rel="stylesheet" />
    <script src="dropzone.min.js"></script>
 
</head>
<body>
 
 
    <form action="upload.php" class="dropzone"></form>
   
</body>
</html>

Как вы наверное заметили мы создали форму с экшеном upload.php, но не создавали никаких инпутов для прикрепления файлов, и не объявляли enctype формы. В этом нет никакой ошибки, все обрабатывается самой библиотекой DropzoneJS. Все, что нам нужно сделать, это присвоить форме класс dropzone. По умолчанию DropzoneJS находит все формы с данным классом и автоматически потрисовывет свой интерфейс.

Вы пожете открыть на исполнение в браузете страницу index.php и убедиться что библиотека срабатывает как задумано. Вот что у меня получилось:

Теперь давайте создадим обработчик загрузки для которого мы уже создали файл upload.php. Привожу пример моего простейшего кода загрузки:

<?php
$ds = DIRECTORY_SEPARATOR;
 
$storeFolder = 'uploads'; // Указываем папку для загрузки
 
if (!empty($_FILES)) { // Проверяем пришли ли файлы от клиента
     
    $tempFile = $_FILES['file']['tmp_name']; //Получаем загруженные файлы из временного хранилища
      
    $targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds;
     
    $targetFile =  $targetPath. $_FILES['file']['name'];
 
    move_uploaded_file($tempFile,$targetFile); // Перемещаем загруженные файлы из временного хранилища в нашу папку uploads
}
?>

Работа с загруженными файлами

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

Для этого обновляем файл upload.php до такого вида (вставлено условие else):

<?php
$ds          = DIRECTORY_SEPARATOR; 
 
$storeFolder = 'uploads';  
 
if (!empty($_FILES)) {
 
    $tempFile = $_FILES['file']['tmp_name'];         
 
    $targetPath = dirname( __FILE__ ) . $ds. $storeFolder . $ds; 
 
    $targetFile =  $targetPath. $_FILES['file']['name']; 
 
    move_uploaded_file($tempFile,$targetFile);
 
} else {                                                           
    $result  = array();
 
    $files = scandir($storeFolder);                 //1
    if ( false!==$files ) {
        foreach ( $files as $file ) {
            if ( '.'!=$file && '..'!=$file) {       //2
                $obj['name'] = $file;
                $obj['size'] = filesize($storeFolder.$ds.$file);
                $result[] = $obj;
            }
        }
    }
     
    header('Content-type: text/json');              //3
    header('Content-type: application/json');
    echo json_encode($result);
}
?>

Как вы можете видеть, мы добавили дополнительный оператор «else», когда HTTP-запрос не содержит файлов. Это используется для обнаружения уже сохраненных файлов на сервере. Давайте посмотрим, что они на самом деле делают.

  1. Функция PHP scandir просматривает папку uploads и возращает массив файлов или значение FALSE елси папка пуста.
  2. Перебираем возвращаемое значение из функции scandir и сохраняем в массив $ result. Помните, мы игнорируем "." И "..", поскольку scandir всегда будет возвращать "." И ".." в качестве допустимого содержимого, относящегося к текущему и предыдущему каталогу.
  3. Выводим правильные заголовки для разметки JSON, а также конвертируем PHP-массив в JSON-строку, используя функцию json_encode. 

Теперь пришло время обновить index.php:

<html>
  
<head>  
  
<link href="css/dropzone.css" type="text/css" rel="stylesheet" />
  
<!-- 1 -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
 
<script src="dropzone.min.js"></script>
 
<script>
<!-- 3 -->
Dropzone.options.myDropzone = {
    init: function() {
        thisDropzone = this;
        <!-- 4 -->
        $.get('upload.php', function(data) {
 
            <!-- 5 -->
            $.each(data, function(key,value){
                 
                var mockFile = { name: value.name, size: value.size };
                 
                thisDropzone.options.addedfile.call(thisDropzone, mockFile);
 
                thisDropzone.options.thumbnail.call(thisDropzone, mockFile, "uploads/"+value.name);
                 
            });
             
        });
    }
};
</script>
 
</head>
  
<body>
  
<!-- 2 -->
<form action="upload.php" class="dropzone" id="my-dropzone"></form>
    
</body>
  
</html>

Что мы тут накодили? Давайте разбиратся:

  1. Увы и ах, мы добавили библиотеку Jquery на нашу страницу. Это на самом деле не необходимость для DropzoneJs. Мы используем только ajax-функцию JQuery $ .get. Вы же на своё усмотрение можете реализовать подобные запросы на vue.js или что вам больше по душе.
  2. Мы добавили в форму элемент ID (my-dropzone). Это необходимо, для того что бы передать значения конфигурации в Dropzone. И для этого мы должны иметь уникальный индификатор указывающий на него. Таким образом мы можем настроить библиотеку, присвоив значения Dropzone.options.myDropzone. 
  3. Инициализируем основную часть редактирования. То, что мы здесь сделали, - передали функцию прослушивания события init Dropzone. Это событие вызывается, когда Dropzone инициализируется.
  4. Получаем массив файлов из «upload.php» посредством ajax.
  5. Создаём mockFile, используя значения с сервера. MockFile - это просто объекты JavaScript со свойствами имени и размера. Затем мы явно вызываем функции Dropbox и добавляем иконки, чтобы поместить существующие файлы в область загрузки Dropzone и создать их миниатюры.

Если вы сделали всё корректно. Загрузите несколько изображений и перезагрузите страницу с формой. Ранее загруженные файлы должны автоматически отображаться в области Dropzone.