How to Upload Files in PHP

When you are creating a website, it is often necessary to give users some way to upload files from their computer to the server. Whether it is a single picture for an avatar or a batch of files sent to place an order, you want to make the upload process easy, fast, and reliable.

PHP provides several different ways to upload files from a user computer to the remote server. You should choose the upload mechanism based on your requirements: whether your users need to upload one or multiple files at a time, send entire folders or just files, work with files of small or very large size, accept only particular file types (like images) or files of any other type. If you upload images, you may want to preprocess them before the upload, i.e. like generate thumbnails, rotate, crop, add watermarks, etc.

Before examining different upload methods let’s see how file upload works in general.

File Upload Basics

There is no magic in the uploading process. It always consists of two parts: a client application, which puts files for upload into a binary data block formed in accordance with an HTTP protocol, and a server, which receives this binary package, parses it, and saves the uploaded files on a server hard disk.

Client applications can be implemented in different ways – using simple <input type=”file”> elements, HTML5, Flash, Java, or even ready-to-use uploader applications. We will examine them a bit later. Meanwhile, let’s take a look at how the server part works.

Using PHP you don’t have to parse the HTTP request manually. After the server receives the upload request it performs the following actions:

  1. Saves uploaded files to a temporary folder on the server (specified by upload_tmp_dir in the php.ini file configuration).
  2. Automatically creates $_FILES collection, which refers to the uploaded files.
  3. Cleans up the temporary folder after the script execution is finished.

So the upload scenario is to go through each element of the $_FILES collection and copy it to an appropriate location. You may also carry out some additional actions such as updating the database, etc.

We’ve figured out how the uploads are organized in PHP at a high level, but now it’s time to look into it in a more detailed fashion. Let’s start with the simplest way – single file upload using the good old Browse button.

Single File Upload

This approach was introduced in early days of the Internet. The client applications consist of an HTML form with the Browse button, which opens a select file dialog, and Submit, which sends a request. Despite the quite limited functionality, it is the simplest way to organize file uploads that will work in any browser and on any platform.

To let your application upload files successfully you should configure PHP by making the following changes to the php.ini file:

  1. file_uploads should be On.
  2. upload_tmp_dir should point to a folder where you want to keep temporary files.
  3. upload_max_filesize should be big enough to allow uploading typical files (but not too big as it may negatively impact the security).

After configuring PHP you should add basic HTML form to the page. The code may look as follows:

<html>                   
    <body>                   
        <form action="upload_file.php" method="post" 
                                       enctype="multipart/form-data">
            <label for="file">Filename:</label>
            <input type="file" name="uploadFile">
            <br>                   
            <input type="submit" value="Submit">
        </form>
    </body>
</html>

As a result, you will get the following upload interface:

Simple file upload interface

Let’s highlight the most important parts:

  1. The form should have the method set to POST.
  2. Its enctype should be multipart/form-data.
  3. The form should contain the action attribute which points to the PHP script that handles file upload.
  4. The input element with type=”file” displays the Choose File button and the field which displays a selected file name.
  5. The name of the input element is used in the PHP script to identify the uploaded file in the $_FILES collection.

After a user clicks the Submit button, the form data will be sent to the server. In our case, it will be sent to the upload_file.php server script that looks like this:

<?php
  if ($_FILES["uploadFile"]["error"] > 0)
    echo "Return Code: " . $_FILES["uploadFile"]["error"] . "<br>";
  else                
  {                
    if (file_exists("upload/" . $_FILES["uploadFile"]["name"]))                
      echo $_FILES["uploadFile"]["name"] . " already exists. ";                
    else                
    {                
      echo $_FILES["uploadFile"]["name"] . " has been uploaded. <br>";
      move_uploaded_file($_FILES["uploadFile"]["tmp_name"],
      "upload/" . $_FILES["uploadFile"]["name"]);
      echo "Stored in: " . "upload/" . $_FILES["uploadFile"]["name"];
    }                
  }                
?>

This upload script tries to save the uploaded file to the upload folder and displays a message indicating whether or not the file is saved successfully. Note that the $_FILES collection key uploadFile is the same as the name of the input tag in the HTML form discussed above.

Although this simple script is enough to transfer a file from the client side to your server, you should configure some security, such as:

  • Limit the size of the POST request and the number of upload files by specifying upload_max_size, post_max_size, and max_file_upload in the php.ini configuration file.
  • Verify the type of the uploaded file. You can use $_FILES["uploadFile"]["type"] or check the extension, but it can be easily spoofed. Thus, we recommend you to use getimagesize() for images or exec() invoking the Unix file program, which determines a file type, for other files.
  • Scan the uploaded files with an antivirus program.

This simple upload method is great when you upload few small files, but it has a number of disadvantages:

  1. It is quite painful to upload a lot of files (a user has to click the Choose file Button for each file).
  2. Uploading large files is not convenient (the page “freezes” until the entire file is transmitted to the server).
  3. There is no validation of the uploaded file on the client side. E.g. if you don’t want to allow a user to upload files larger than 2MB, you won’t be able to decline a larger file until it is completely uploaded.

Let’s see what we should do to go beyond this old-fashioned HTML form.

Multiple File Upload

The previous example demonstrated how to upload one file at a time. If you need to upload multiple files, you can add several input tags in the HTML form, but a user will need to choose every file separately, which is inconvenient, especially when uploading a large number of files.

Fortunately, all modern browsers now support a more extended version of HTML also known as HTML5. In particular, it includes the so-called File API (http://www.w3.org/TR/FileAPI/) which allows you to create more advanced file uploading using JavaScript. Another powerful platform is Flash, though it is a bit outdated. There are a number of open source HTML5/Flash-based uploaders with a big community of developers available, for example:

  • Uploadify is a jQuery plugin which allows you to build an upload interface similar to Gmail attachments.
  • Fine Uploader is a JavaScript plugin tool with multiple file selection, progress bar, auto and manual upload, image preview, etc.
  • Plupload is an upload tool based on several platforms, which includes some image processing functionality.

These uploaders are great to provide your users with a simple multiple file upload interface, but sometimes it is not enough. For example, you may need to:

  • Pre-process images before upload (resize, generate thumbnails of several sizes, add watermarks, extract EXIF, let users to crop images, etc.).
  • Upload entire folders and keep the structure of the folders on the server.
  • Upload hundreds of files.
  • Upload files of hundreds of MB or even several GB.
  • Automatically restore the broken uploads.
  • Speed up the upload process.

All these scenarios are ideal for Aurigma’s Upload Suite. You can do it with few lines of code.

Get a 30-day trial Upload Suite includes premium uploaders based on various technologies (HTML5, Flash, Java, ActiveX) for any server technology - ASP.NET and PHP, classic ASP and JSP, Ruby-on-rails and node.js.