How to Upload Files with HTML & PHP

Goal: To upload a file to the web server, using HTML and PHP

Prerequisites: A good grasp on HTML forms, and a working knowledge of PHP is helpful for understanding the guide, but not necessary to get a working product (simply use the last code snippit).

There are many scripts available on the web to assist with uploading files to a server using a web browser. However, it isn't difficult to create a simple user interface that allows someone to upload files using a simple HTML form and PHP script.

In this example, I am going to use an HTML form, and it will submit to the same page. Lets start our file. We'll call it FileUpload.php.

FileUpload.php:

<form action="FileUpload.php" method="post" enctype="multipart/form-data">
    <label for="upload">File:</label>
    <input type="file" name="upload" id="upload"><br/>
    <input type="submit" name="submit" value="Upload">
</form>

If we look at the first line in the body, we see our typical html form construct. The action is indicating that we'll submit this form to FileUpload.php (aka this same file), we are using a post request, and the really important part, enctype="multipart/form-data" is indicating that this form may contain binary data, which is crucial to allow for the file upload to be able to take place. Now that we have our form, we can build a little PHP logic into this file to indicate whether or not we just submitted the form (and we'll indicate that the file was uploaded), or if we are waiting on the user to submit (in which case we'll show them the form we just built). It will look something like this:

<?php
    if (isset($_FILES['upload'])) {
        //todo: handle the uploaded file
        echo "Your file was uploaded successfully";
    } else {
    ?>
        <form action="FileUpload.php" method="post" enctype="multipart/form-data">
            <label for="upload">File:</label>
            <input type="file" name="upload" id="upload"><br/>
            <input type="submit" name="submit" value="Upload">
        </form>
    <?php
    }
?>

So the reason we're doing this check is because if they submitted a file, I didn't want to show them the form again. If you were submitting your file to a different page obviously you wouldn't need any of this logic, but since I kept it contained in a single file I needed to come up with the different use cases. So in order to do that I simply checked if the upload was submitted to the page or not by using the isset($_POST['upload']) check (to clarify we use "upload" because it is the name attribute on our file input). Now, we need to actually handle the file upload. Right now it's actually being placed in the web servers temporary file storage location which is defined in the php.ini file on the upload_tmp_dir setting. You can retrieve this location by using the function sys_get_temp_dir()for the generic directory, and if you want to know the file location you can use $_FILES['upload']['tmp_name'] (where upload is your form field name).

Moving on to handling the uploaded file. At this point, we're uploading a file, and it's stored in a temporary location on the server. This brings us great joy that we are able to upload files, but it's all for naught if we don't move the file to a more permanent location on disk. So lets get to it:

<?php
    if (isset($_FILES['upload'])) {
        $uploadDir = '/var/www/uploads/'; //path you wish to store you uploaded files
        $uploadedFile = $uploadDir . basename($_FILES['upload']['name']);
        if(move_uploaded_file($_FILES['upload']['tmp_name'], $uploadedFile)) {
            echo 'File was uploaded successfully.';
        } else {
            echo 'There was a problem saving the uploaded file';
        }
        echo '<br/><a href="FileUpload.php">Back to Uploader</a>';
    } else {
    ?>
        <form action="FileUpload.php" method="post" enctype="multipart/form-data">
            <label for="upload">File:</label>
            <input type="file" name="upload" id="upload"><br/>
            <input type="submit" name="submit" value="Upload">
            </form>
        <?php
    }
?>

At last, we have a working file uploader, that takes an uploaded file, and moves it over to our specified upload directory. This script should get most novices to file uploading started. There are of course many improvements that could be made on the script, and I'll list some of these considerations below but it'll be up to you to implement the code.

Additional Considerations & Tips for uploading files with PHP

  • PHP maximum upload size: php.ini settings will cause PHP to throw warings/errors when the limits are exceeded. These limit settings that should be adjusted are upload_max_filesize and post_max_size
  • Client side file size validation: This can be important to do, mainly because in the event where a file is to large you will have to first waste the users time as they upload a file which then gets rejected by the server, and to top that off they may end up with an ugly non-user friendly message on the screen.
  • Catching files that exceed the upload limits: can often be done in php by using a hidden input field with a name of MAX_FILE_SIZE which has a value that is equal to the number of bytes that the maximum upload size is. While this can be bypassed by a malicious user, those are the one's who you typically don't care if they see an ugly error message when the server finally gets around to handling it.
  • $_FILES['fieldName']['tmp_name'] is blank: - This can happen if your upload limits aren't set up to handle the size of the file you are trying to upload. Check the PHP.ini file settings again.
  • Other File Attributes: Some other $_FILE['fieldName'] attributes you might find useful include (taken from php.net):
    • $_FILES['fieldName']['name'] - The original name of the file when it was uploaded.
    • $_FILES['fieldName']['type'] - The mime type of the file, if the browser was able to provide this information. An example of this would be image/gif. This mime type is not checked server side so it may be better to implement your own mime type function to retrieve this info based on the file extension.
    • $_FILES['fieldName']['size'] - The size, in bytes, of the uploaded file.
    • $_FILES['fieldName']['tmp_name'] - The temporary path and filename where the uploaded file was stored on the server.
    • $_FILES['fieldName']['error'] - The error code associated with this file upload.
  • Paths must exists ahead of time: - Fair warning that the directory you are trying to move your upload to has to exist before you try and move the file there. This can often be done using the mkdir command.
Loading Conversation