Задать вопрос
jasonOk
@jasonOk
Легче болтать, чем код писать

Насколько правилен такой подход?

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

Первое:
В любой момент он может загрузить картинку, а затем тут же её убрать. Следовательно она навсегда останется нигде неиспользуемая. Как контролировать подобные действия?
У меня возникла идея хранить в mongoDB данные о каждом изображении, (путь, к какой оно статье и т.д.) а когда человек сохраняет изменения статьи, проверять, какие изображения используются в ней, а все остальные, принадлежащие к этой статье, но неиспользуемые, находить в mongoDB и удалять через цикл, насколько это оправдано?

Второе:
Я так до конца и не понял, как правильно хранить изображения на сервере.
Недолго думая у меня получилось следующее:
$path = md5($handle->file_src_name.substr(time(), 3)); // Хэш названия — md5(имя картинки + текущее время)
$handle->file_new_name_body = substr($path, 4); // имя изображения берём с 5-го символа
$handle->Process('files/images/t/'.substr($path, 0,1).'/'.substr($path, 1, 1).'/'.substr($path, 2, 2)); // путь сохранения изображения

Что неверно в данном подходе?

В общем:
- Как контролировать изображения на сервере, чтобы не накапливались ненужные?
- Какой способ хранения изображений самый рациональный, если не сказать правильный; как раскидывать файлы по каталогам?
  • Вопрос задан
  • 2253 просмотра
Подписаться 12 Оценить Комментировать
Пригласить эксперта
Ответы на вопрос 6
EireenK
@EireenK
В любой момент он может загрузить картинку, а затем тут же её убрать. Следовательно она навсегда останется нигде неиспользуемая.

Можно и не загружать картинки на сервер при редактировании статьи, а показывать их, например, через Blob URLs. А при сохранении уже делать загрузку и заменять эти блоб-урлы на реальные адреса. Здесь можно посмотреть пример использования (кнопка "Import image with Blob URLs")
Ответ написан
saboteur_kiev
@saboteur_kiev
software engineer
Можно просто периодически запускать мусорщик, который будет сканировать все статьи и помечать удалять неиспользуемые картинки.

Например запускается проверка, обновляется таймстамп в базе картинки, которая была найдена. затем сортировка по таймстампу покажет какие картинки не были найдены во время этой проверки.

Можно просто добавить такую опцию в админку и запускать вручную, или раз в неделю/месяц в момент низкой активности.

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

Раскидывать файлы по каталогам можно как удобно. Если ссылка на файл в базе - то вообще нет никаких особых правил, просто для удобства обслуживания хранить так, чтобы не тормозила файловая система (например не больше нескольких тысяч файлов в одной подпапке).
Ответ написан
Комментировать
uvelichitel
@uvelichitel
habrahabr.ru/users/uvelichitel
Я выдаю token и отправляю на API imgur.com с моими credentials. habrahabr позволяет просто вставить ссылку на любое хранилище и только сравнительно недавно сделал свое. В любом случае мне кажется картинкохранилище правильней рассматривать как отдельный миросервис, а не часть монолитного приложения. Держать хранилище у себя очень затратно по SSD дискам и по трафику, поэтому представляется разумным воспользоваться специализированным third_party располагающим CDN, таких много в том числе бесплатных. Подтирать черновики выглядит невежливым по отношению к пользователю, может быть он картинки для следующей статьи заготовил или еще не решил какие лучше, а вы их в мусор.
Ответ написан
Sivkoff
@Sivkoff
Web Developer
Можно хранить картинки в папках с id статьи. Пример пути к картинке при такой схеме хранения:
files/images/{article_id}/{file_name}

Из плюсов:
  • крайне простое удаление изображений - просто удаляем папку, имя которой совпадает с ID статьи
  • можно хранить файлы с осмысленными именами, не боясь коллизий

UPD. Прошу прощения, упустил первую часть вопроса.
Хранение дополнительных данных о файлах неизбежно, если нужно более продвинутое управление изображениями. Удалять конечно же лучше во время сохранения статьи.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
В любой момент он может загрузить картинку, а затем тут же её убрать
Это обычная работа со множествами.
В момент сохранения сравниваем два списка: загруженные картинки (для текущей статьи) и находящиеся в статье.
Лишние - удаляем из хранилища!

UPD: Я храню медиа-контент в папке статьи:
storage/articles/{article_id}/images/
storage/articles/{article_id}/videos/
storage/articles/{article_id}/sounds/
storage/articles/{article_id}/3D/
Ответ написан
Комментировать
trevoga_su
@trevoga_su
у меня так сделано на моем сайте объявлений:

картинка грузится через скрытый фрейм. по факту успешной загрузки фрейм в основную страницу рисует инпуты с id изображения:
<input value="130006" name="thumbnail[]" type="hidden">

и идет запись информации об изображении в таблицу связи, где ID сущности, за которой закреплено изображение - стоит NULL

картинку после загрузки можно удалить - просто исключив этот input из DOM, но картинка останется на серваке - для поиска таких картинок ходит крон. он удаляет все изображения и информацию о них из таблицы связи, где ID сущности is null и время добавления картинки больше часа (ну, что бы наверняка)

после того, как сохраняется сущность в БД, в таблице связи проставляется ID сущности, т.е. идет закрепление картинок за сущностью.

+ когда я отображаю список объявлений, шаблон должен знать, есть ли у объявления изображение и сколько их.
для этого на таблице связей висит триггер, который при insert/update/delete
1. считает кол-во картинок сущности и записывает их в таблицу сущьности
2. находит картинку первую добавленную по времени и записывает информацию о ней в таблицу сущьности - это позволяет выводить список объявлений и изображение без доп запросов.

Вот URL картинки добавленной в 10:11 и сразу же "удаленной". Часа через три её уже не будет на серваке.

все ясно?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы