35

Can any one suggest the best practice to generate unique file names for file uploads to avoid duplicate Entries?

Thanks In Advance.

Adamski
  • 5,769
  • 9
  • 32
  • 32
  • 1
    The safest way would be an incremental counter. – Pekka Dec 06 '10 at 23:24
  • @Pekka how can i use a counter for image upload –  Jun 28 '12 at 14:27
  • 1
    Use this as a file name and add extension at the end. Here's an example with .jpg images: hash('ripemd160',time().mt_rand(10,1000)).".jpg" So it's basically unix time in seconds, + a random number between 10 and 1000, and then it's all encoded into a hash string – Mladen Jul 02 '18 at 13:02

6 Answers6

36

I usually either create a UID using uniqid() function for the filename or create a folder with the name of the username who is uploading the file and leave the original filename. The disadvantage of the first one is that you will have to save the original filename somewhere to show to the user.

ryudice
  • 36,476
  • 32
  • 115
  • 163
10

This function may help:

http://php.net/manual/en/function.uniqid.php

You may also consider looking into using a hash of the files contents such as:

http://php.net/manual/en/function.sha1-file.php

Kevin Stock
  • 506
  • 4
  • 9
  • 2
    Beware of collisions when using hash as a filename. Better use a hash salted with a random string. – luxcem Jan 21 '14 at 13:37
8

You could use the unix timestamp of when the file was uploaded. If you expect several uploads to occur simultaneously, you could append a unique user ID or part of the original filename.

Colin O'Dell
  • 8,386
  • 8
  • 38
  • 75
8

Something like this:

$filename = md5(date('Y-m-d H:i:s:u'));

Since MD5 hashes are not guaranteed to be unique, it's a good idea to check for collisions using file_exists($filename). In that case, rerun the above.

afilina
  • 878
  • 1
  • 11
  • 25
cnizzardini
  • 1,196
  • 1
  • 13
  • 29
  • 11
    Hashes are not unique. – afilina Aug 11 '15 at 22:11
  • @afilina Why aren't hashes unique? – James P. Sep 20 '17 at 06:28
  • There is the potential for a collision with MD5 or any hashing function, but that is unlikely for most use-cases. My original response is from 2010. Use sha256, possibility of a collision is very, very low https://stackoverflow.com/questions/4014090/is-it-safe-to-ignore-the-possibility-of-sha-collisions-in-practice – cnizzardini Sep 22 '17 at 01:53
  • @JamesP. Think of hashes like a once-sentence summary of a movie. Multiple movies can have the same summary. – afilina Mar 26 '18 at 21:00
  • 3
    The suggested code `$filename = md5(date('Y-m-d H:i:s:u'));` does not seem to work. From the PHP documentation: "Note that date() will always generate 000000 since it takes an integer parameter" Test: `echo date('Y-m-d H:i:s:u');` output: `2019-03-22 07:30:28:000000` Better solution would be: `$date = DateTime::createFromFormat('U.u', microtime(TRUE)); $filename = md5($date->format('Y-m-d H:i:s:u')));` – chris342423 Mar 22 '19 at 14:35
  • Also note: If you really need unique names it is absolutely essential to do the collision checking with file_exists(), because running the code twice(for example if you want to create names for two files) without any delay between will most likely produce the exact same filename! Example: `for ($i = 0; $i < 5; $i++) { $date = DateTime::createFromFormat('U.u', microtime(true)); echo $date->format('Y-m-d H:i:s.u').PHP_EOL; }` Output: `2019-03-22 15:09:02.070900 2019-03-22 15:09:02.070900 2019-03-22 15:09:02.071000 2019-03-22 15:09:02.071000 2019-03-22 15:09:02.071000 ` – chris342423 Mar 22 '19 at 15:09
4

There's tempnam and tmpfile, if you want to create files, or this question.

Community
  • 1
  • 1
EboMike
  • 76,846
  • 14
  • 164
  • 167
  • Works well, with one caveat - calling it creates the file on the disk, which is not always what you want. – crafter Jun 28 '23 at 11:41
1

$username.$timestamp.$randomNumber

or you could hash this if you don't want people to know details of when it was uploaded and by whom

Freddie
  • 1,717
  • 2
  • 16
  • 23