upload images through php using unique file names

I am currently in the process of writing a mobile app with the help of phonegap. One of the few features that I would like this app to have is the ability to capture an image and upload it to a remote server…

I currently have the image capturing and uploading/emailing portion working fine with a compiled apk… but in my php, I am currently naming the images “image[insert random number from 10 to 20]… The problem here is that the numbers can be repeated and the images can be overwritten… I have read and thought about just using rand() and selecting a random number from 0 to getrandmax(), but i feel that I might have the same chance of a file overwriting… I need the image to be uploaded to the server with a unique name every-time, no matter what… so the php script would check to see what the server already has and write/upload the image with a unique name…

any ideas other than “rand()”?

I was also thinking about maybe naming each image… img + date + time + random 5 characters, which would include letters and numbers… so if an image were taken using the app at 4:37 am on March 20, 2013, the image would be named something like “img_03-20-13_4-37am_e4r29.jpg” when uploaded to the server… I think that might work… (unless theres a better way) but i am fairly new to php and wouldn’t understand how to write something like that…

my php is as follows…

$new_image_name = "image".rand(10, 20).".jpg";
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);

Any help is appreciated…
Thanks in advance!
Also, Please let me know if there is any further info I may be leaving out…

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

You may want to consider the PHP’s uniqid() function.
This way the code you suggested would look like the following:

$new_image_name = 'image_' . date('Y-m-d-H-i-s') . '_' . uniqid() . '.jpg';
// do some checks to make sure the file you have is an image and if you can trust it
move_uploaded_file($_FILES["file"]["tmp_name"], "/home/virtual/domain.com/public_html/upload/".$new_image_name);

Also keep in mind that your server’s random functions are not really random. Try random.org if you need something indeed random. Random random random.

UPD: In order to use random.org from within your code, you’ll have to do some API requests to their servers. The documentation on that is available here: www.random.org/clients/http/.

The example of the call would be: random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new. Note that you can change the min, max and the other parameters, as described in the documentation.

In PHP you can do a GET request to a remote server using the file_get_contents() function, the cURL library, or even sockets. If you’re using a shared hosting, the outgoing connections should be available and enabled for your account.

$random_int = file_get_contents('http://www.random.org/integers/?num=1&min=1&max=1000000000&col=1&base=10&format=plain&rnd=new');

Solution 2

You should use tempnam() to generate a unique file name:

// $baseDirectory   Defines where the uploaded file will go to
// $prefix          The first part of your file name, e.g. "image"
$destinationFileName = tempnam($baseDirectory, $prefix);

The extension of your new file should be done after moving the uploaded file, i.e.:

// Assuming $_FILES['file']['error'] == 0 (no errors)
if (move_uploaded_file($_FILES['file']['tmp_name'], $destinationFileName)) {
    // use extension from uploaded file
    $fileExtension = '.' . pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
    // or fix the extension yourself
    // $fileExtension = ".jpg";
    rename($destinationFileName, $destinationFileName . $fileExtension);
} else {
    // tempnam() created a new file, but moving the uploaded file failed
    unlink($destinationFileName); // remove temporary file

Solution 3

Have you considered using md5_file ?
That way all of your files will have unique name and you would not have to worry about duplicate names. But please note that this will return same string if the contents are the same.

Also here is another method:

do {
  $filename = DIR_UPLOAD_PATH . '/' . make_string(10) . '-' . make_string(10) . '-' . make_string(10) . '-' . make_string(10);
} while(is_file($filename));

return $filename;

* Make random string
* @param integer $length
* @param string $allowed_chars
* @return string
function make_string($length = 10, $allowed_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890') {
  $allowed_chars_len = strlen($allowed_chars);

  if($allowed_chars_len == 1) {
    return str_pad('', $length, $allowed_chars);
  } else {
    $result = '';

    while(strlen($result) < $length) {
      $result .= substr($allowed_chars, rand(0, $allowed_chars_len), 1);
    } // while

    return $result;
  } // if
} // make_string

Solution 4

Function will create a unique name before uploading image.

// Upload file with unique name
if ( ! function_exists('getUniqueFilename'))
    function getUniqueFilename($file)
        if(is_array($file) and $file['name'] != '')
            // getting file extension
            $fnarr          = explode(".", $file['name']);
            $file_extension = strtolower($fnarr[count($fnarr)-1]);

            // getting unique file name
            $file_name = substr(md5($file['name'].time()), 5, 15).".".$file_extension;
            return $file_name;

        } // ends for is_array check
            return '';

        } // else ends

    } // ends

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply