More secure PHP image upload class tutorial
June 8th, 2007In the internet are many php image upload tutorials, but most of them are not so secure. In this tutorial i try to teach you how to write not very complex but secure image upload class. First of all we should define class ant it variables:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?php class image_upload { var $tmp_image; var $max_file_size = 100000; var $max_width = 800; var $max_height = 600; var $allow_types = array( 'image/jpeg', 'image/png', 'image/gif' ); var $errors; } ?> |
For variables $max_file_size, $max_width, $max_height and $allow_types I assigned default values. There are two more variables its $errors for error printing and $tmp_image for $_FILES[’xxxx’] global variable.
Now then we have defined class and variables we can make some standard functions for image upload class. First we need to know if given file is really image so we use function exif_imagetype() witch reads firs file bytes and returns true if file is image else it returns false. (Note: exif_imagetype() function will work only if module exif is installed in server.)
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php function is_image () { if (exif_imagetype($this->tmp_image['tmp_name'])) { $this->errors[] = 'Uploaded file is not image'; return true; } else { return false; } } |
To check uploaded image type (mime type) i use next function. It searches for uploaded image type in $allow_types types array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function is_type () { if (in_array($this->tmp_image['type'], $this->allow_types)) { return true; } else { $this->errors[] = 'Image type is not acceptable'; return false; } } |
Next I check if image is suitable size:
1 2 3 4 5 6 7 8 9 10 11 12 | function is_size () { if ($this->tmp_image['type'] <= $this->max_file_size) { return true; } else { $this->errors[] = 'Image file size is too big'; return false; } } |
To check image dimensions I call getimagesize() function it returns array with image parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function is_dimensions () { $size = getimagesize($this->tmp_image['tmp_name']); $width = $size[0]; $height = $size[1]; if ($width <= $this->max_width && $height <= $this->max_height) { return true; } else { $this->errors[] = 'Image is too height or too width'; return false; } } |
Finally I wrote image upload function it has two parameters $dest – upload destination and $safe for safe image upload witch by default is false.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | function upload_image ($dest, $safe=false) { if ($safe) { $status = true; $status = $this->is_image(); $status = $this->is_type(); $status = $this->is_size(); $status = $this->is_dimensions(); return ($status)?move_uploaded_file( $this->tmp_image['tmp_name'], $dest) :false; } else { return move_uploaded_file( $this->tmp_image['tmp_name'], $dest); } } |
Now class is ready for use. For class test I wrote a simle script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <?php include('upload.class.php'); $IM = new image_upload(); if ($_FILES['photo']) { $IM->tmp_image = $_FILES['photo']; if ($IM->upload_image($_SERVER['DOCUMENT_ROOT']. '/tnimg/'.$IM->tmp_image['name'], true)) { echo 'Image uploaded'; } else { foreach ($IM->errors as $error) { echo $error.'<br />'; } } } ?> <form method="post" enctype="multipart/form-data" action=""> <label for="photo">Photo file</label> <input type="file" name="photo" /> <input type="submit" name="submit" value="Upload" /> </form> |


























