PHP: Хранение файловых мест... что если перезаписать?

В настоящее время я использую Zend Framework и у меня есть форма для загрузки файла. Аутентифицированный пользователь имеет возможность загрузить файл, который будет храниться в каталоге в приложении, а местоположение хранится в базе данных. Таким образом, он может быть отображен в виде файла, который можно загрузить.

<a href="/upload-location/filename.pdf">Download</a>

Но я замечаю, что файл с тем же именем перезапишет файл в каталоге загрузки. Нет сообщения об ошибке, равно как и приращение имени файла. Поэтому я думаю, что файл должен быть перезаписан (или никогда не загружен).

Какие рекомендации я должен знать при загрузке, перемещении или хранении этих файлов? Должен ли я всегда переименовывать файлы, чтобы имя файла всегда было уникальным?

3 ответа

Решение

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

Например, если пользователь загружает my_file.pdf, мы будем:

  • сохранить строку в БД, содержащую:
    • id; автоинкремент, первичный ключ - "123", например
    • имя, данное пользователем; так что мы можем отправить правильное имя, когда кто-то пытается загрузить файл
    • тип содержимого файла; application/pdf или что-то подобное, например.
    • "наше имя: file-123 например
  • когда есть запрос к файлу с id=123, мы знаем, какой физический файл должен быть выбран ('file-' . $id) и отправил.
  • и мы можем установить заголовок для отправки правильного "логического" имени в браузер, используя имя, которое мы сохранили в БД, для диалогового окна "сохранить как"
  • то же самое для типа контента, кстати

Таким образом, мы уверены:

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

Продолжая ответ Паскаля МАРТИНА:

Если в качестве имени используется идентификатор, вы также можете придумать стратегию именования каталогов. Мне больше не нужно, чтобы получить /somedir/part1ofID/part2OfID из файловой системы, чем /somedir/theWholeID но это позволит вам выбрать, сколько файлов будет храниться в одном каталоге из того, как вы разбили идентификатор для формирования пути и имени файла.

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

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

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

Другие вопросы по тегам