Задать вопрос
@an543

Нужно ли хранить путь к картинке в БД?

Всем привет. Я понимаю, что вопрос избитый, но мнений в интернете очень много. У меня в каждом посту 1 основное фото плюс 10-15 дополнительных, все привязаны к одному посту. Нужно ли сохранять путь к картинке в базе, если да то зачем. Или можно сохранять к примеру /img/id_post/main.jpg . Так же с аватарами например /img/ava/ava_id_user.jpg.
  • Вопрос задан
  • 807 просмотров
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 5
@yayashitoya
Если картинка ровно 1 на пост и лежит всегда в одном месте - то не нужно.
Если картинок много, но лежат они в одном месте - то путь не нужен, только имя файла.
Если картинка может лежать в разных местах, то нужно и путь хранить.
Ответ написан
@vardoLP
Ват ю сэй эбаут май мама?!
Ну если у вас есть возможность редактирования поста и возможность загружать или изменять картинки, то вам определенно нужно хранить эти пути в бд. Иначе как вы будете их выводить на страницах редактирования.
Ответ написан
php666
@php666
PHP-макака
Все имена файлов загружаем как хэш от md5 - нет ни одной причины их называть человекопонятными именами.

Имея имя файла делаем разграничитель директорий. Например, файл называется cc49db9055039eacc73d46d10af535cc.jpeg
Соответствунно делаем директории (если они еще не созданы) при загрузке файла - /i/800x800/c/c/4/
Последние 3 директории - создаются автоматом при сохранении изображения. Соответсвуют первым трем буквам имени файла.

В базе храним так:
ID записи картинки
ID сущности
cc49db9055039eacc73d46d10af535cc.jpeg - имя файла
2018-10-31 12:03:27 - дата загрузки

По имени файла всегда можно получить путь:

<?php
class DirectoryGenerator
{
    /**
     * Имя файла.
     *
     * @var string
     */
    private $file_name;

    /**
     * Глубина создаваемой вложенности директорий.
     * @var int
     */
    private $depth = 3;

    /**
     * DirectoryGenerator constructor.
     *
     * @param string $file_name имя файла
     */
    public function __construct(string $file_name)
    {
        if (!strlen($file_name)) {
            throw new \InvalidArgumentException(__METHOD__ . ': Указан параметр нулевой длинны');
        }

        $this->file_name = $file_name;
    }

    /**
     * Создает директории (если они ещё не созданы) на основе имени файла
     * (например, d2d8f9c20083bd8483ac5d5526f923b9.jpeg) и возвращает путь.
     *
     * @param string $destinationDir директория назначния
     * @return string путь, например: i\700x600\d\2\d\
     */
    public function create(string $destinationDir): string
    {
        $destinationDir = rtrim($destinationDir, '\/');

        for ($i = 0; $i < $this->depth; $i++) {
            $destinationDir .= DIRECTORY_SEPARATOR . $this->file_name[$i];

            if (!is_dir($destinationDir)) {
                if (!mkdir($destinationDir, 0775)) {
                    throw new \RuntimeException(__METHOD__ . ': Не удалось создать директорию ' . $destinationDir);
                }
            }
        }

        return $destinationDir . DIRECTORY_SEPARATOR;
    }

    /**
     * На основе имени файла (например, d2d8f9c20083bd8483ac5d5526f923b9.jpeg)
     * возвращает путь к файлу для HTTP, вида /d/2/d/8/f/.
     *
     * @todo переименовать, название не отражает сути
     * @return string HTTP-путь к файлу
     */
    public function getHttpPath(): string
    {
        $destinationDir = '';

        for ($i = 0; $i < $this->depth; $i++) {
            $destinationDir .= '/' . $this->file_name[$i];
        }

        return $destinationDir . '/';
    }
}
Ответ написан
Комментировать
@karminski
Senior React.JS Developer
Если в посте только одна картинка, вы можете вообще не хранить ее название. Сохраняйте картинку с именем равным номеру или коду поста, и ссылайтесь на нее. Исключаем лишний запрос к бд.
Ответ написан
@Tvolly
Как уже сказали, если картинка поста поменяется, и вы перепишите ./.../main.jpg, браузер клиента все ещё будет некоторое время хранить старую картинку в кеше.
Отключать кеш не выгодно, добавлять суффикс не логично
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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