user3430617
user3430617

Reputation: 21

Any way to generate random file name when uploading?

I have created a website that uploads anything. The problem I have is that I'm new to all this. I have tried every code that generates random strings but I have nothing. Here is the code anyway:

<?php

$fileName = $_FILES["file1"]["name"]; // The file name
$fileTmpLoc = $_FILES["file1"]["tmp_name"]; // File in the PHP tmp folder
$fileType = $_FILES["file1"]["type"]; // The type of file it is
$fileSize = $_FILES["file1"]["size"]; // File size in bytes
$fileErrorMsg = $_FILES["file1"]["error"]; // 0 for false... and 1 for true
if (!$fileTmpLoc) { // if file not chosen
    echo "ERROR: Please browse for a file before clicking the upload button.";
    exit();
}
if(move_uploaded_file($fileTmpLoc, "uploads/$fileName")) {
    echo '<a href="uploads/'.$fileName.'"><input type="button" class="button"    
    value="Download" /></a>';
} else {
    echo "move_uploaded_file function failed";
}

?>

Could there be a way to generate random file names so that when someone uploads the same name as a file already on the server, it does not overwrite the existing file?

Upvotes: 2

Views: 7070

Answers (9)

Vasilii Suricov
Vasilii Suricov

Reputation: 954

Check this and let me know if you will find any weakness:

$ php -a
Interactive shell

php > while(file_exists($fullPath = sys_get_temp_dir() .DIRECTORY_SEPARATOR .uniqid()));
echo $fullPath;

UNIX result looks like /tmp/65c21e77ca3d4

In the vanishingly small chance of stumbling upon an already existing file, this piece of code will give a different name. But the chance of creating this file in another thread before yours is still not 0

Upvotes: 0

Farid Movsumov
Farid Movsumov

Reputation: 12725

$fileName = "image_".uniqid();

The uniqid() function generates a unique ID based on the microtime (current time in microseconds).

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

Upvotes: 4

HaRsH
HaRsH

Reputation: 313

//you can use both random and time function to get more unique no count:


 $fileName = 'mypic'.mt_rand(100000, 999999).'_'.time(). $_FILES["file1"]["name"];

use are:-
mt_rand(100000, 999999)// for randm no.
time()// for timestring
$_FILES["file1"]["name"]//also you can give your file name

Upvotes: 0

Santosh Yadav
Santosh Yadav

Reputation: 460

You can use md5(microtime()) to get unique file name even you uploading more than one file at a time

Upvotes: 2

Kalzem
Kalzem

Reputation: 7492

Because a folder is limited to 65535 files, you need to create subfolders. This technique creates 3 subfolders (with 3 characters each) depending on the timestamp then creates a random filename.

For more randomness and future-proofness (because using time() and microtime() is weak if you have multiple users uploading at the same time) :

//Get the extension of the file
$fileExtension = end(explode(".", $_FILES['item']['name']));
$randOctalName = openssl_random_pseudo_bytes(5);
$randName = bin2hex($randOctalName).".".$fileExtension;

//Save it into uploads/123/456/789/
$path = "";
$timestamp = time();
$path = substr($timestamp,0,3)."/".substr($timestamp,3,3)."/".substr($timestamp,6,3)."/";
$relativePath = './uploads/'.$path;$timestamp = time();
$path = substr($timestamp,0,3)."/".ubstr($timestamp,3,3)."/".substr($timestamp,6,3)."/";
$relativePath = './uploads/'.$path;
_r_mkdir($relativePath);

And the mkdir recursive function :

private function _r_mkdir($path, $mode = 0755, $recursive = true)
{
    if(empty($path)){
        return false;
    }

    if($recursive) {
        $toDo = substr($path, 0, strrpos($path, '/'));
        if($toDo !== '.' && $toDo !== '..'){
            _r_mkdir($toDo, $mode);
        }
    }

    if(!is_dir($path)){
        mkdir($path, $mode);
    }

    return true;
}

Upvotes: 1

Gopal1216
Gopal1216

Reputation: 437

Study this code thoroughly. This is all you need.

<?php
    if (isset($_FILES["avatar"]["name"]) && $_FILES["avatar"]["tmp_name"] != "")
    {
      $fileName = $_FILES["avatar"]["name"];
      $fileTmpLoc = $_FILES["avatar"]["tmp_name"];
      $fileType = $_FILES["avatar"]["type"];
      $fileSize = $_FILES["avatar"]["size"];
      $fileError = $_FILES["avatar"]["error"];
      $kaboom = explode(".",$fileName);
      $fileExt = end($kaboom);
      list($width,$height) = getimagesize($fileTmpLoc);
      if($width < 10 || $height < 10)
      {
        header("location: ../message.php?msg=ERROR: That image has no dimensions");
        exit();  
      }
      $db_file_name = rand(100000000000,999999999999).".".$fileExt;
      if($fileSize > 5048576)
      {
        header("location: ../message.php?msg=ERROR: Your image file was larger than 1mb");
        exit();   
      }
      else if (!preg_match("/\.(gif|jpg|png)$/i", $fileName) ) 
      {
        header("location: ../message.php?msg=ERROR: Your image file was not jpg, gif or png type");
        exit();
      }
      else if ($fileErrorMsg == 1) 
      {
        header("location: ../message.php?msg=ERROR: An unknown error occurred");
        exit();
      }
      $sql = "SELECT avatar FROM users WHERE username='$log_username' LIMIT 1";
      $query = mysqli_query($db_conx,$sql);
      $row = mysqli_fetch_row($query);
      $avatar = $row[0];
      if($avatar != "")
      {
        $picurl = "../user/$log_username/$avatar"; 
        if (file_exists($picurl))
        unlink($picurl);
      }
      $moveResult = move_uploaded_file($fileTmpLoc,"../user/$log_username/$db_file_name");
      if ($moveResult != true) 
      {
        header("location: ../message.php?msg=ERROR: File upload failed");
        exit();
      }
      include_once("../php_includes/image_resize.php");
      $target_file = "../user/$log_username/$db_file_name";
      $resized_file = "../user/$log_username/$db_file_name";
      $wmax = 200;
      $hmax = 300;
      img_resize($target_file, $resized_file, $wmax, $hmax, $fileExt);
      $sql = "UPDATE users SET avatar='$db_file_name' WHERE username='$log_username' LIMIT 1";
      $query = mysqli_query($db_conx, $sql);
      mysqli_close($db_conx);
      header("location: ../user.php?u=$log_username");
      exit();
    }
    ?>

Upvotes: -1

viji
viji

Reputation: 313

try this

$now=date('d/m/y');
if(move_uploaded_file($fileTmpLoc, "uploads/$now.$fileName"))

it will add date infront of the filename

Upvotes: -3

Suleman Ahmad
Suleman Ahmad

Reputation: 2113

you can use microtime time to make sure file name is unique.

 $file_name = "custom_name_" . microtime(); 

Upvotes: 1

WhiteLine
WhiteLine

Reputation: 1991

use the timestamp (or microtime), so you know it is necessarily different every time

$fileName = "image_".time();

TimeStamp

Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT).

Microtime

microtime() returns the current Unix timestamp with microseconds. This function is only available on operating systems that support the gettimeofday() system call.

Upvotes: 0

Related Questions