На моем сайте я позволяю пользователям загружать файлы.
Если файл действителен и загружен, он перемещается в папку (используя PHP).
Все пользователи загружаются в одну и ту же папку.
Мне кажется, мне нужно переименовать загруженные файлы.
Есть ли что-то вроде соглашения об именах по умолчанию, позволяющего пользователям загружать файлы с тем же именем?
Стандартных соглашений нет, но есть несколько лучших практик:
Что-то вроде:
/uploads/USER/ or /uploads/[USER/]YEAR/[MONTH/[DAY/[HOUR/[MINUTE/]]]]
Это будет иметь некоторые преимущества:
Переименование или нет – это выбор, который вам нужно будет сделать, в зависимости от вашего веб-сайта, базы пользователей, насколько вы неясны, и, очевидно, ваша архитектура. Вы предпочитаете иметь файл с именем kate_at_the_beach.jpg
или 1304357611.jpg
? Это действительно зависит от вас, чтобы решить, но поисковые системы (очевидно), как и первые, лучше.
Одна вещь, которую вы должны сделать, – это всегда санировать и нормализовать имена файлов , лично я бы разрешал только следующие символы: 0-9
, az
, AZ
, _
, -
.
– если вы выберете этот санитарный алфавит. нормализация в основном означает просто преобразование имени файла в нижний или верхний регистр (во избежание потери файлов, если, например, вы переключитесь с чувствительной к регистру файловой системы на регистр, нечувствительный к регистру, например Windows).
Вот пример кода, который я использую в phunction (бесстыдная плагин, я знаю : P ):
$filename = '/etc/hosts/@Álix Ãxel likes - beer?!.jpg'; $filename = Slug($filename, '_', '.'); // etc_hosts_alix_axel_likes_beer.jpg function Slug($string, $slug = '-', $extra = null) { return strtolower(trim(preg_replace('~[^0-9a-z' . preg_quote($extra, '~') . ']+~i', $slug, Unaccent($string)), $slug)); } function Unaccent($string) // normalizes (romanization) accented chars { if (strpos($string = htmlentities($string, ENT_QUOTES, 'UTF-8'), '&') !== false) { $string = html_entity_decode(preg_replace('~&([az]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|tilde|uml);~i', '$1', $string), ENT_QUOTES, 'UTF-8'); } return $string; }
Поскольку в записи документа move_uploaded_file()
указано:
Если файл назначения уже существует, он будет перезаписан.
Таким образом, прежде чем вы вызове move_uploaded_file()
вы лучше проверите, существует ли файл, если он это делает, тогда вы должны (если вы не хотите потерять старый файл) переименовать новый файл, обычно добавляя токен / случайный / уникальный токен перед расширением файла, сделав что-то вроде этого:
if (file_exists($output . $filename) === true) { $token = '_' . time(); // see below $filename = substr_replace($filename, $token, strrpos($filename, '.'), 0); } move_uploaded_file($_FILES[$input]['tmp_name'], $output . $filename);
Это приведет к вложению $token
перед расширением файла, как я уже говорил выше. Что касается выбора значения $token
вас есть несколько вариантов:
time()
– обеспечивает уникальность каждую секунду, но отстой обрабатывает дубликаты файлов (Dummy text, чтобы следующая строка форматировалась как код.)
$token = '_' . md5_file($_FILES[$input]['tmp_name']);
Надеюсь, поможет! 😉
Такого соглашения нет, но, как правило, имя генерируется случайным образом, чтобы сделать предположение менее вероятным. Разрешить имя файла без дезинфекции настоятельно не рекомендуется, используйте по крайней мере белый подход, в котором вы удаляете все символы, кроме тех, что указаны в белом списке. Ключом является безопасность, загрузка является рискованной функцией и может быть опасной, если ее не обрабатывать должным образом.
Просто сделайте какое-то соглашение самостоятельно. Например, вы можете просто сохранить файлы как userId_timestamp
в папке и сохранить исходное имя файла в некоторой базе данных. Или вы просто делаете это userId_originalFilename
или какую-то другую комбинацию вещей, которые делают ее уникальной.
В аналогичном случае я сохраняю информацию в таблице (с идентификатором пользователя как внешний ключ), отформатируйте автонумерный идентификатор с ведущими нулями для имени файла (то есть 000345.jpg) и сохраните исходное имя в таблице.
Не могли бы вы использовать некоторую комбинацию имени пользователя и даты загрузки?