Как временно хранить файлы с помощью Laravel?

#php #ajax #laravel-5

#php #ajax #laravel-5

Вопрос:

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

Сортировку и удаление предварительных просмотров можно довольно легко выполнить с помощью javascript, но помимо этого мне трудно понять, как правильно сделать все остальное. Моя первоначальная идея заключалась в том, чтобы получить массив файлов js из входных данных, переместить его в другой массив и работать с ним, как только пользователь взаимодействует с предварительным просмотром изображений, которые будут отображаться с помощью FileReader .

Как только он отправит форму, я бы создал FormData объект, удалил текущие файлы во входных данных и добавил все допустимые:

 var formdata = new FormData(document.getElementById('upload-form'));
if (formdata.has('pic[]') amp;amp; validFiles.length) {
   formdata.delete("pic[]");
   var len = validFiles.length;
   for (i = 0; i < len; i  ) {
      formdata.append("pic[]", validFiles[i]);
   }

}
  

Если вы разбираетесь в js, вы уже можете видеть, что этот подход имеет серьезные проблемы, когда дело доходит до обратной совместимости, поскольку методы FormData.delete(..) .append(..) и .has(..) не поддерживаются старыми браузерами (включая Chrome 50 и ниже или практически любой IE).)

Хорошо, отбросьте эту идею. Моя вторая идея заключалась в том, чтобы сделать следующее:

  1. Пользователь выбирает изображения для добавления
  2. Загрузите указанные изображения с помощью ajax и временно сохраните их где-нибудь с помощью Laravel
  3. Возврат предварительного просмотра изображений
  4. Позвольте пользователю использовать предварительные просмотры для изменения порядка файлов или их удаления и отслеживать, что он делает.
  5. После отправки формы возьмите всю остальную информацию, выясните, какие файлы должны храниться вечно, а какие следует удалить и сохранить.

Теперь я не совсем уверен, как это сделать. Я подумал, что у меня может быть каталог tmp для этих изображений, сгенерировать какую-то строку в качестве имени каталога, связанного с сеансом пользователя, сохранить там файлы и сохранить имя каталога с помощью Session .

Проблема в том, что Session , похоже, имеет глобальный тайм-аут и не может быть установлен на истечение, скажем, через 15 минут. Другая проблема, которую я вижу, заключается в том, что Session по истечении срока действия и пользователь решает не загружать изображения, они останутся на сервере навсегда, поскольку я не смог найти метод, который позволил бы мне выполнить код по Session истечении срока действия.

Итак, каков правильный способ временного хранения файлов в Laravel? Или я иду в неправильном направлении, и можете ли вы увидеть лучший способ сделать то, что я пытаюсь сделать?

Заранее спасибо за любые советы.

Ответ №1:

Ваша вторая идея, похоже, правильная, но слегка измененная.

Как насчет этого:

 <?php
// Collect a list of files in a $tempLocation (modify this to your usage)
collect(File::files($tempLocation))->map(function($file) {
    return [
        'file' => $file,
        'basename' => pathinfo($file)['filename']
    ];
// Filter out the non-numeric files and those that are before now
})->filter(function($a) {
    return is_numeric($a['basename']) amp;amp; $a['basename'] < time();
// Delete each file that is outdated
})->each(function($file) {
    try { unlink($file['file']); } catch($e) { /* Fill me in */ }
});
  

Тогда ваш обычный рабочий процесс будет заключаться в загрузке файлов ваших пользователей с номенклатурой:

{timestamp timeout}.{ext}

Затем вы бы поместили вышеупомянутую функцию в ежедневный или еженедельный cron. Все «старые» файлы будут удалены. Если ваш пользователь хочет сохранить файл, просто переместите файл в другое место, в временный каталог или переименуйте его во что-то нечисловое.

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

Надеюсь, это поможет.