Как назвать загруженные файлы в php, чтобы предотвратить их перезапись? - PullRequest
0 голосов
/ 25 апреля 2010

Я пытаюсь добавить пользовательские статьи на мой сайт (только для администраторов). С каждой статьей вы можете загрузить до 3 изображений. Моя база данных настроена так

Статья

id
user_id
title
body
date_added
last_edited

Фотографии

id (auto_increment)
article_id

Сначала я сохраняю статью в базе данных, затем загружаю фотографию (временно), затем создаю новую запись фотографии в базе данных, сохраняя article_id. Затем я переименовываю загруженную фотографию, чтобы она была такой же, как первичный ключ записи фотографии, и была бы png.

$filename = $photo->id . '.png';

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

Спасибо

Ответы [ 5 ]

1 голос
/ 25 апреля 2010

Если изображение использует первичный ключ с автоинкрементом в качестве имени, абсолютно невозможно получить два изображения с одинаковым именем.

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

Единственный способ перезаписать изображения - это сброс счетчика автоинкремента БД и для этого необходимо удалить предыдущие записи в таблице, иначе СУБД снова пересчитает счетчик в запись с самым высоким идентификатором на столе.

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

1 голос
/ 25 апреля 2010

Для чего это стоит, вот метод, который я включил в свои классы загрузки файлов, чтобы убедиться, что я не перезаписываю существующие файлы.Я передаю имя загружаемого файла ($ _FILES [$ img_field] ["name"]) и каталог для сохранения файла в качестве параметров, так что это остается общим методом.

 private function unique_file_upload($filename, $dir) {
      $filename = preg_replace("/[^.\w]/",'_',$filename);
      $filename = preg_replace("/__+/",'_',$filename);
      preg_match("/^(.*)\.(\w{2,4})$/",$filename,$f);
      if ( file_exists( $dir . $filename ) ) {
          $num = 1;
          while ( file_exists( $dir . $filename ) ) {
              preg_match("/^(.*)\.(\w{2,4})$/",$filename,$f);
              preg_match("/(\d+)$/",$f[1],$n);
              if ($n[1]) {
                  $x = $n[1];
                  $num = $n[1] + 1;
                  $num .= '.';
                  $filename = preg_replace("/$x\./",$num,$filename);  
              }
              else {
                  $filename = $f[1] . $num . '.' . $f[2];
              }
          }
      }
      return $filename;
  }
1 голос
/ 25 апреля 2010

Нет ничего плохого в том, чтобы просто использовать первичный ключ базы данных для имени файла.

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

Как указывает другой ответ, переименование файла, заканчивающегося на .png, не сделает его png. Возможно, вы захотите взглянуть на встроенную в PHP библиотеку GD (или посмотреть ImageMagick), если хотите конвертировать форматы изображений.

1 голос
/ 25 апреля 2010

Хэш их.

Я использовал PHP-функцию MD5 для хеширования изображений, когда они загружались в галерею. Он имеет два основных преимущества: разные изображения не будут перезаписывать друг друга, идентичные изображения будут . Это означает, что каждое уникальное изображение будет иметь уникальное имя. Примите загрузку, хэшируйте сохраненные данные, создайте имя файла (hash.extension), проверьте существующий файл. Если он существует, удалите временный файл и просто используйте существующую копию. В противном случае переименуйте временный файл и сохраните его. Возможно, вам придется отслеживать, что ссылается на каждый файл (чтобы убедиться, что вы не удаляете используемый файл в другом месте), но это может сэкономить много места для дубликатов и является простым способом получения уникальных имен.

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

0 голосов
/ 25 апреля 2010

Правильный способ - хранить файлы с идентификатором первичного ключа соответствующей записи. Чтобы обработать «но тогда это просто бесполезное число», вы можете сохранить исходное имя файла в таблице «photos». Если вы разрешаете использование нескольких типов изображений, вы также можете сохранить тип mime.

Затем вы используете простой скрипт, который извлекает имя файла из базы данных и передает его клиенту с заголовком Content-disposition: attachment; filename=$filename. Таким образом, даже если имя файла на вашем сервере (скажем) «3527», клиент увидит загрузку «originalimagefilename.jpg» или чего-либо другого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...