Form for uploading files using PHP5

Posted under » PHP on 6 January 2016

Some of my PHP uploaders are not working, and I then realised that it was because of my recent upgrade to PHP5 which cause those made during the PHP4 era to malfunction.

$HTTP_POST_FILES is the main culprit and was depreciated. Now we use $_FILES.

I wrote a similar uploader back in 2009. However, this time I made some improvement to the security aspect of uploading as it could be exploited to upload malicious scripts.

<form action="uploader.php" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>
 

Now look at the uploader.php

<¿php
$target_dir = "/var/www/reports/";
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
$uploadOk = 1;
$imageFileType = pathinfo($target_file,PATHINFO_EXTENSION);
// Check if image file is a actual image or fake image
if(isset($_POST["submit"])) {
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
// return mime type ala mimetype extension
	$finfo = finfo_open(FILEINFO_MIME_TYPE);
	$mine = finfo_file($finfo, $_FILES['fileToUpload']['tmp_name']);

    if($check !== false) {
        echo "File is an image - " . $check["mime"] . ". ";
        $uploadOk = 1;
    } else {
        echo "File is not an image - " . $mine . ". ";
        $uploadOk = 0;
    }
}
// Check if file already exists
if (file_exists($target_file)) {
    echo "Sorry, file already exists.";
    $uploadOk = 0;
}
// Check file size
if ($_FILES["fileToUpload"]["size"] > 500000) {
    echo "Sorry, your file is too large.";
    $uploadOk = 0;
}
// Allow certain file formats
if($imageFileType != "jpg" && $imageFileType != "png" && $imageFileType != "jpeg"
&& $imageFileType != "gif" ) {
    echo "Sorry, only JPG, JPEG, PNG & GIF files are allowed.";
    $uploadOk = 0;
}
// Check if $uploadOk is set to 0 by an error
if ($uploadOk == 0) {
    echo "Sorry, your file was not uploaded.";
// if everything is ok, try to upload file
} else {
    if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $target_file)) {
        echo "The file ". basename( $_FILES["fileToUpload"]["name"]). " has been uploaded.";
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}
?> 

The file is identified as an image by the getimagesize() command. You can see the mime type by $check["mime"].

If it is not an image file, say a word or pdf for eg, another way of telling the mime type is by finfo_file() command. See also mime-content-type.

It is customary for uploads to check the filesize.

The type of image is identified by the PATHINFO_EXTENSION. Here is an explanation

<¿php
print_r(pathinfo("/testweb/test.txt"));
?>  

Will get.

Array
(
[dirname] => /testweb
[basename] => test.txt
[extension] => txt
) 
 

It is better to rename the file in case file exist instead of just giving an error message. So

$rndom = "3cf9"
$target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
// Check if file already exists
if (file_exists($target_file)) {
$target_file = $target_dir . $rndom.basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
} else { $rndom = "";}

Another way of doing this or if you want to add the random number before the extension and/or you have more than one file.. As you can separate basename from extension, then change the basename instead.

 $name = pathinfo($_FILES["fileToUpload"]["name"], PATHINFO_FILENAME);
 $extension = pathinfo($_FILES["fileToUpload"]["name"], PATHINFO_EXTENSION);
$increment = ''; //start with no suffix
while(file_exists($name . $increment . '.' . $extension)) {
    $increment++;
}
$basename = $name . $increment . '.' . $extension;
 

Once everything is in order, it will move the file to its location from /tmp to $target_dir. Sometimes there is a permission issue at the $target_dir. This folder must be writable and owned by www-data or apache to 644 at least. Please read about how to do this.

For more info.

If may also upload and store your image or pdf to the MySQL table as binary.

web security linux ubuntu python django git Raspberry apache mysql php drupal cake javascript css AWS data