How to give the uploaded file a unique filename?

The code in the book*:

<?php
//pick a file extension
if (preg_match('/^image\/p?jpeg$/i', $_FILES['upload']['type']))
{
$ext='.jpg';
}
else if (preg_match('/^image\/gif$/i', $_FILES['upload']['type']))
{
$ext = '.gif';
}
else if (preg_match('/^image\/(x-)?png$/i', $FILES['upload']['type']))
{
$ext = '.png';
}
else
{
$ext = '.unknown';
}

//The complete path/filename
$filename = 'C:/uploads/' . time(). $_SERFER['REMOTE_ADDR'] . $ext;

//Copy the file (if it is deemed safe)
if (!is_uploaded_file($FILES['upload']['tmp_name']) or
!copy($_FILES['upload']['tmp_name'], $filename))
{
$error = "Could not save file as $filename!";
include $_SERVER['DOCUMENT_ROOT'] . '/includes/error.html.php';
exit();
}
?>

I don’t understand why use $_FILES[‘upload’][‘tmp_name’] to replace $filename because $filename is already unique. I also wanna know if $_FILES[‘upload’][‘tmp_name’] is always unique.

*PHP and MySQL Novice to Ninja - page 286

I’m not sure, but checking to see if the type of file is an image won’t necessarily work. This also applies to checking to see if the file has a .jpg, .gif, or .png file extension. I would suggest to use mime_content_type, but since mime_content_type is deprecated, you should use fileinfo. This is because someone could create a .txt file. Add in executable codes and then rename that file to something like look_at_me.jpg. The image does indeed have a .jpg and it is an image, but the actual mime_content_type is plain text or .txt. This could be a huge security risk because the file itself was not made using an image editor or a camera of any sort.

The suggestion for safety is very helpful. I wanna use fileinfo instead but do you have any suggestion that where I can find out how to use fileinfo. Thank you\ :slight_smile:

If you click on mime_content_type and fileinfo in my post. It will lead you to the PHP documents that have those instructions. If you can’t seem to find the links. You can use this small modification I have written up.

<?php
// Check to see if the form was submitted yet.
// Don't rely on isset($_POST['submit'])
// This is the first rookie mistake people tend to do when it comes to a form being submitted.
// When you rely on isset($_POST['submit']), someone can use the tab key or simply go into a text field, submit what they want and the script will fail because the button was not set.
// Read the comments in the link below to see why you shouldn't use isset($_POST['submit']) and should start using $_SERVER['REQUEST_METHOD']
// http://stackoverflow.com/questions/10943060/isset-postsubmit-vs-serverrequest-method-post#comment14373814_10943179
if($_SERVER['REQUEST_METHOD'] == 'POST') {
     $finfo = finfo_open(FILEINFO_MIME_TYPE); // Grab the fileinfo.
     $mime = finfo_file($finfo, $_FILES['upload']['tmp_name']); // Get the fileinfo from the uploaded file.
     finfo_close($finfo); // Close the fileinfo.
     $array = array('image/gif', 'image/jpeg', 'image/png'); // Make an array of mime types you want to allow.
     // Check to see if the mime type of the uploaded file is in the array. If it is not, show them an error.
     if(in_array($mime, $array)) {
           //The complete path/filename
           $filename = 'uploads/' . time(). $_SERVER['REMOTE_ADDR'] . '.jpg'; // Never trust a user's file extension. Make a default file extension.
           //Copy the file (if it is deemed safe)
           if(!is_uploaded_file($_FILES['upload']['tmp_name']) or !copy($_FILES['upload']['tmp_name'], $filename)) {
                 $error = "Could not save file as $filename!";
                 include $_SERVER['DOCUMENT_ROOT'] . '/includes/error.html.php';
                 exit();
           } else {
                 print("Success!"); // Their file has the correct mime type and it was successfully uploaded.
           }
     } else {
          print("An error has occurred"); // Give them a custom error. You shouldn't tell them exactly that they have uploaded a wrong type of file. Just give them a custom error.
          exit();
     }
} else {
?>
<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="upload">
<button type="submit">Submit</button>
</form>
<?php
}
?>
1 Like

Two ways to insure unique.
If you are also inserting anything into a database, get the last insert ID.
Or use PHP’s uniqueid uniqid

Thank you so much for the modification! With the comment, it’s easy to read.

Have a great day.^^

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.