Я сделал сценарий загрузки на PHP. Как избежать перезаписи файлов?

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

Как я могу это сделать с PHP?

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

Поэтому просто переименуйте его в какую-то схему своего собственного проектирования. Это мой совет.

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

Не используйте file_exists () по той причине, что он возвращает true (в системах * nix, по крайней мере, поскольку каталоги являются специализированными файлами), если это значение является каталогом. Вместо этого используйте is_file ().

Например, скажем, что-то терпит неудачу, и у вас есть строка вроде:

 $path = "/path/to/file/" . $file; // Assuming $file is an empty value, if something failed for example if ( true === file_exists($path) ) { echo "This returns true"; } if ( true === is_file($path) ) { echo "You will not read this"; } 

Это вызвало несколько проблем в прошлом для меня, поэтому я всегда использую is_file (), а не file_exists ().

Я использую функции даты и времени для генерации случайного имени файла в зависимости от времени загрузки.

Предположим, вы отправляете файл из формы, в которой у вас есть вход с именем incomingfile файла, например:

 <input type="file" id="incomingfile" name="incomingfile" /> 

Прежде всего, я использую, чтобы «упорядочить» имя файла и скопировать его из временного каталога по умолчанию во временный каталог. Это необходимо для обработки специальных символов. У меня были проблемы, когда я не принял эту практику.

 $new_depured_filename = strtolower(preg_replace('/[^a-zA-Z0-9_ -.]/s', '_', $_FILES["incomingfile"]["name"])); copy($_FILES["incomingfile"]["tmp_name"], 'my_temp_directory/'.$new_depured_filename); 

Со следующим фрагментом кода я проверяю, существует ли файл, если это так, я нахожу новое имя и, наконец, копирую его. Например, если я хочу написать файл с именем myimage.jpg и он уже существует, я переименую ожидающий файл в myimage__000.jpg . Если это существует, я переименую ожидающий файл в myimage__001.jpg и т. Д., Пока не найду несуществующее имя файла.

 $i=0; // A counter for the tail to append to the filename $new_filename = $new_depured_filename; $new_filepath='myfiles/music/'.$new_filename; while(file_exists($new_filepath)) { $tail = str_pad((string) $i, 3, "0", STR_PAD_LEFT); // Converts the integer in $i to a string of 3 characters with left zero fill. $fileinfos = pathinfo($new_filepath); // Gathers some infos about the file if($i>0) { // If we aren't at the first while cycle (where you have the filename without any added strings) then delete the tail (like "__000") from the filename to add another one later (otherwise you'd have filenames like myfile__000__001__002__003.jpg) $previous_tail = str_pad((string) $i-1, 3, "0", STR_PAD_LEFT); $new_filename = str_replace('__'.$previous_tail,"",$new_filename); } $new_filename = str_replace('.'.$fileinfos['extension'],"",$new_filename); // Deletes the extension $new_filename = $new_filename.'__'.$tail.'.'.$fileinfos['extension']; // Append our tail and the extension $new_filepath = 'myfiles/music/'.$new_filename; // Crea il nuovo percorso $i++; } copy('my_temp_directory/'.$new_depured_filename, $new_filepath); // Finally we copy the file to its destination directory unlink('my_temp_directory/'.$new_depured_filename); // and delete the temporary one 

Используемые функции:
strtolower
preg_replace
копия
Файл существует
str_pad
PathInfo
str_replace
разъединить

Чтобы проверить, существует ли файл, вы можете использовать функцию file_exists .

Чтобы вырезать имя файла, вы можете использовать функцию pathinfo .

я использую

 $file_name = time() . "_" . $uploaded_file_name;