PHP Assistance with Image Uploads

Shelldon

Active Member
Joined
May 30, 2012
Messages
53
Reaction score
0
I'm needing a bit of direction here please.

I'm busy building a site where users can upload an image to use as a profile pic and I'm trying to understand the process. In my mind the following would happen..

User uploads image which is given a unique identifier (random string). Random string is in the "user" database table while the actual image is hosted on the cdn, the url of which is recored in the "user" database table.

Is this right?

Thanks in advance.
 
You could just use an md5 of the user id for the "random" string but do append a random timestamp as your salt to make filenames less predictive.

Also consider auto resizing images once uploaded to ensure you don't run out of disk space after users decide to upload 20Mb images - it happens. You can also crop them.

Backing up images is important and there are many options for this.
 
Here is a very simple sample, don't know if it will help you...

<?php
mysql_connect("localhost", "dbuser", "dbpassword") or die(mysql_error());
mysql_select_db("databasename") or die(mysql_error());

//$anyotherfields = mysql_real_escape_string(trim($_POST['anyotherfields']));

$query = "INSERT INTO yourtable SET anyotherfields='$anyotherfields";

if ($_FILES['image'])
{
$file_name = $_FILES['image']['name'];
$query .= ", image='$file_name'";
}


mysql_query($query) or die(mysql_error());

$upload_dir = '/home/yourroot/public_html/whereyouuploadto/';

if ($_FILES['image'])
{
$upload_file = $upload_dir . mysql_insert_id() . '_' . $_FILES['image']['name'];
move_uploaded_file($_FILES['image']['tmp_name'], $upload_file);
}

?>

This assumes you already have a MySQL database and you can just add an image field.

1. This script, without testing it, should upload a single image to a folder you specified.
2. It will rename the actual image file with the database id field (which should already be on auto increment and unique) in front of the file name in order to prevent duplicate file names on the server.
3. It will add the image name uploaded into the database.
 
Last edited:
Thanks for the help guys, I think I understand the process now
 
1. This script, without testing it, should upload a single image to a folder you specified.
2. It will rename the actual image file with the database id field (which should already be on auto increment and unique) in front of the file name in order to prevent duplicate file names on the server.
3. It will add the image name uploaded into the database.

This script is incredibly wrong in so many ways, but suffice to say, it will not correctly rename the image file (the actual file name will be set, but the record in the DB will be the old name), it will not ensure no duplicates (what happens when I upload a file named _1.jpg and 1_1.jpg already exists) and it will not add the image path to the DB.

What it does do is introduce a large number of security vulnerabilities, not least of which is allowing arbitrary file uploads.
 
This script is incredibly wrong in so many ways, but suffice to say, it will not correctly rename the image file (the actual file name will be set, but the record in the DB will be the old name), it will not ensure no duplicates (what happens when I upload a file named _1.jpg and 1_1.jpg already exists) and it will not add the image path to the DB.

What it does do is introduce a large number of security vulnerabilities, not least of which is allowing arbitrary file uploads.

Yes, yes, yes and yes...

There is a lot of work to be done on the script, but I used it as an example for the OP to look at the process of allowing users to upload an image and change a profile pic.

As for duplicate file names, this one is sufficient and will prevent duplicate files. Take a look at the script again.
 
I suggest you upload "_filename.jpg" when "1_filename.jpg" already exists.

What happens when "_filename.jpg" gets renamed with primary key to "1_filename.jpg" ?

It is better (as cbrunsdonza suggested) to make an entirely unique file name
 
Last edited:
I suggest you upload "_filename.jpg" when "1_filename.jpg" already exists.

What happens when "_filename.jpg" gets renamed with primary key to "1_filename.jpg" ?

It is better (as cbrunsdonza suggested) to make an entirely unique file name

You do realize that the script above automatically renames every file uploaded by adding the unique id field in front of the file name, before it moves the file to the specified folder, right?

So, if the first file uploaded is _image.jpg, the script will rename it to 1_image.jpg. If the second upload has a file called 1_image.jpg, the script will automatically rename it to 21_image.jpg - and this all happens before the image is moved to the folder.
 
Last edited:
Well, the second upload would actually be named "2_1_image.jpg" in that case; but there is still a possibility of a collision.

It would be wise to check "file_exists()" or name it something guaranteed to be unique.
 
I don't see a finfo check?
http://php.net/manual/en/function.finfo-file.php

$allowed_types = array ( 'application/pdf', 'image/jpeg', 'image/png' );
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$detected_type = finfo_file( $fileInfo, $_FILES['datei']['tmp_name'] );
if ( !in_array($detected_type, $allowed_types) ) {
die ( 'Please upload a pdf or an image ' );
}
finfo_close( $fileInfo );
Something like that

Googling a bit:
if (!$img = @imagecreatefromstring(file_get_contents($filename))) {
throw new Exception("{$filename}: Invalid image content.");
}
Seems to be also recommended just in case someone wrapped up their file in an image.
https://stackoverflow.com/questions/6755192/how-to-check-uploaded-file-type-in-php


What's the size of the image? If it's small enough, you might want to dump it into the DB as a blob.
https://mybroadband.co.za/vb/showthread.php/853817-Blob-vs-File-system-storage

Basically depends on usage/file size. If the file is above 2MB, near always file. If it's a lot of thumbnails that are accessed often (e.g. forum profile pics like MyBB has on the left), then a DB blob might be better as it can be accessed faster.

There is an interesting Microsoft paper on it. This is a bit old now though (2006): https://www.microsoft.com/en-us/research/wp-content/uploads/2006/04/tr-2006-45.pdf
 
Why bother with naming issues? If its just for profile pics then use the db table's PK as the key, FK link it to the user and upload either a binary image or store it with a filename on disk as e.g. PK or PK_FK.png etc.
 
Thanks for everyones thoughts on this - I should have been clearer.

Users would be able to upload a number of images, there's no limit, but images would be under 2mb each. So I'm just trying to figure if my thinking is right or whether there's a better way to go about it.

So user uploads an image, php allocates a file-name to that image, maybe user_id + md5 or something similar. The image file name is then saved to a database table with it's url. When presenting a profile, php reads the url from the database and fetches the image.
 
Why bother with naming issues? If its just for profile pics then use the db table's PK as the key, FK link it to the user and upload either a binary image or store it with a filename on disk as e.g. PK or PK_FK.png etc.

The difference between a senior developer and a junior is that the senior has failed more times than the junior has tried. ;)
 
Top
Sign up to the MyBroadband newsletter
X