MrSeth
MrSeth

Reputation: 51

How to deny identical images being uploaded with PHP

I want to create a way to search a directory by Imagetype or similiar variable.. before the image is uploaded to that diretory.

My goal is to search the BLOB of images in that directory with php, and if any result match (meaning there will duplicate uploads of the same image) return with "File already uploaded".

This will only pertain to image files...

Here is the code I think I can add too..

// Elements (values) of $_FILES['ImageFile'] array
//let's access these values by using their index position
$ImageName      = str_replace(' ','-',strtolower($_FILES['ImageFile']['name'])); 
$ImageSize      = $_FILES['ImageFile']['size']; // Obtain original image size
$TempSrc        = $_FILES['ImageFile']['tmp_name']; // Tmp name of image file stored in PHP tmp folder
$ImageType      = $_FILES['ImageFile']['type']; //Obtain file type, returns "image/png", image/jpeg, text/plain etc.

//Let's use $ImageType variable to check wheather uploaded file is supported.
//We use PHP SWITCH statement to check valid image format, PHP SWITCH is similar to IF/ELSE statements 
//suitable if we want to compare the a variable with many different values
switch(strtolower($ImageType))
{
    case 'image/png':
        $CreatedImage =  imagecreatefrompng($_FILES['ImageFile']['tmp_name']);
        break;
    case 'image/gif':
        $CreatedImage =  imagecreatefromgif($_FILES['ImageFile']['tmp_name']);
        break;          
    case 'image/jpeg':
    case 'image/pjpeg':
        $CreatedImage = imagecreatefromjpeg($_FILES['ImageFile']['tmp_name']);
        break;
    default:
        die('Unsupported File, Please Check File And Try Again!'); //output error and exit
}

Upvotes: 0

Views: 254

Answers (1)

Yanick Rochon
Yanick Rochon

Reputation: 53516

Among other things, these have to be considered in such system :

  1. User may upload the same filename, but with different contents (warn, update, replace, duplicate?)
  2. User may upload the same file content, but under a different name (warn, update, replace, duplicate?)

In a system I had to design, a few years ago, files uploaded had to be replaced only on same user, different users could upload the exact same file name or content (it had to be linked to the existing file name to avoid duplicated data), but if the content was different, the file had to exist twice with the exact same name (assigned to two different users).

The Db table looked something like :

CREATE TABLE user_files (
   id INT UNSIGNED NOT NULL PRIMARY KEY,
   user_id INT UNSIGNED NOT NULL,
   ...   -- other fields
   filename VARCHAR(256) NOT NULL,  -- the original file name
   file_sha VARCHAR(40) NOT NULL,   -- the content SHA1
   file_md5 VARCHAR(16) NOT NULL,   -- the content MD5
   file_lnk VARCHAR(1024) NOT NULL, -- uniqid(sha1(originalFilename)) *
   ...   --- other fields
)

[*] the file_lnk field is the target file on the server, including a computed path based on some heuristics

Basically, I used sha1_file and md5_file on the uploaded file (still in the upload temp directly) and looked in the database for the uploaded file; The SHA1 or the current user id and file name (ie: SELECT ... WHERE file_sha = <computed_sha1> OR (user_id = <current_uid> AND filename = <uploaded_filename>)) was queried from the database to check for any match then looped through the resultset with an algorithm to check the best matching result :

  • if the SHA1 matched anything then the content was probably already uploaded, the MD5 field was then compared also.
    • if the file belonged to the same user (same user_id), then filename was only updated if necessary
    • in any other case, the file content was to be linked and a new row was created in the database to the existing content (same file_lnk)
  • if the user_id and filename was the same, then same file name was uploaded
    • if the same file content was linked with another user, a new row was created, generating a new file_lnk and updating file_sha and file_md5.
    • in any other case, and the file content was replaced with this new content (replacing the actual file_lnk file only)
  • in any other case, a new file and db table row was created

Upvotes: 2

Related Questions