Механизм PHP, запрещающий пользователям загружать один и тот же файл дважды - PullRequest
4 голосов
/ 25 ноября 2011

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

В обоих случаях я хотел бы использовать exec("openssl md5 " . $file['upload']['tmp_name']) для определения хеша MD5 файла сразу после его загрузки.Затем я проверю базу данных на наличие идентичного хэша MD5 и, если он будет найден, я просто не буду завершать загрузку.

Однако в документации move_uploaded_file я нашел этот комментарий:

Предупреждение. Если вы сохраняете хэш md5_file в базе данных, чтобы хранить записи о загруженных файлах, что полезно для предотвращения загрузки пользователем одного и того же файла дважды, имейте в виду, что после использования move_uploaded_file хеш md5_file изменяется!И вы не можете найти соответствующий хеш и удалить его в базе данных при удалении файла.

Это действительно так? Меняется ли хэш MD5 файла в каталоге tmp после его перемещения в постоянное местоположение? Я не понимаю, почему это так.И независимо от того, существует ли другой, лучший способ гарантировать, что один и тот же файл не загружается в файловую систему несколько раз?

Ответы [ 5 ]

1 голос
/ 05 декабря 2012

Попробуйте переименовать загруженный файл в уникальный идентификатор.Используйте это:

$dest_filename = $filename;
        if (RENAME_FILE) {
      $dest_filename = md5(uniqid(rand(), true)) . '.' . $file_ext;
         }

Дайте мне знать, если это поможет:)

1 голос
/ 25 ноября 2011

Если вы убеждены по всем причинам, приведенным здесь в ответах, и решили вообще не использовать md5 (я все еще не уверен, ХОТИТЕ ли вы или ДОЛЖНЫ использовать хеш), вы можете просто добавить что-то уникальное для каждогоПользователь и время загрузки для каждого имени файла.Таким образом, вы получите более читаемые имена файлов.Что-то вроде: $filename = "$filename-$user_ip_string-$microtime";.Конечно, перед этим все три переменные должны быть готовы и отформатированы, само собой разумеется.

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

1 голос
/ 25 ноября 2011

Казалось бы, это действительно так. Вскоре я тоже просматривал документы. Но почему бы вам не поделиться контрольной суммой md5 до с помощью move_uploaded_file и сохранить это значение в вашей базе данных, связав его напрямую с новым файлом? Таким образом вы всегда можете проверить загруженный файл и существует ли этот файл в вашей файловой системе.

Для этого требуется база данных, но у большинства есть доступ к ней.

1 голос
/ 25 ноября 2011

Разве вы не должны вместо этого использовать exec("openssl md5 " . $file['upload']['name']) имя? Я думаю, что временное имя отличается от загрузки до загрузки.

0 голосов
/ 25 ноября 2011

Нет, в общем случае хеш не изменяется каким-либо магическим образом move_uploaded_file .

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

В случае, если вы md5 () имя файла, ничего не изменится.

Рекомендуется переименовывать загруженные файлы с уникальным именем.

Но не забудьте найти файл , чтобы окончательно сохранить файл, это вне корневой папки вашего документа вашего vHost. Находясь там, его нельзя скачать без использования PHP-скрипта.

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

...