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, к которой она прикреплена или связана с записями.