Uploading Files with PHP

It is possible to write a PHP script that will upload a file from the client's computer to the server, which can be very useful for certain types of application (for example, a virtual learning environment that allows students to upload completed coursework in electronic format). The following HTML document creates a form that allows the user to select a file for uploading to the server:


<html>
  <body>

    <form action="upload_01.php" method="post"
      enctype="multipart/form-data">
      <table>
        <tr>
          <td>
            Filename:
          </td>
          <td>
            <input type="file" name="file" id="file">
          </td>
        </tr>
        <tr>
          <td colspan="2" align="right">
            <input type="submit" name="submit" value="Submit">
          </td>
        </tr>
      </table>
    </form>

  </body>
</html>


The enctype attribute used in the <form> tag tells the browser which content-type to use (multipart/form-data in this case) when submitting the form. The multipart/form-data type is used when binary data, such as the contents of a file, is to be uploaded. The type attribute for the <input> tag is set to "file" to tell the browser to treat the input as a file. The browser will display a browse button next to the input text box to allow the user to browse for a file on the local file system. Enter the code above into a text editor and save it with the filename "upload_01.html" in the "htdocs" directory of your "xampp" directory. Run the XAMPP server, then type the following URL into the browser's address bar:


http://localhost/upload_01.html


You should see a web page that looks something like the screenshot below (note that we have found wide variations in the way the page is displayed in different browsers, so don't worry if it doesn't look quite like this).


The output from upload_01.html

The output from upload_01.html


A basic script that allows you to upload a file to the server is given below.


<?php
if ($_FILES["file"]["error"] > 0)
{
  echo "Error: " . $_FILES["file"]["error"] . "<br>";
}
else
{
  echo "Upload: " . $_FILES["file"]["name"] . "<br>";
  echo "Type: " . $_FILES["file"]["type"] . "<br>";
  echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br>";
  echo "Stored in: " . $_FILES["file"]["tmp_name"];
}
?>


Enter the code above into a text editor and save it with the filename "upload_01.php" in the "htdocs" directory of your "xampp" directory. Run the XAMPP server, and type the following URL into the browser's address bar:


http://localhost/upload_01.html


When the web page upload_01.html is displayed, click on the Browse button and select a file to upload (it doesn't really matter at this stage which file you select), then click on the Submit button. You should see a page that looks something like the illustration below.


The output from upload_01.php

The output from upload_01.php


Note that at this stage, the script has not actually saved the file to a permanent storage location on the server. It simply creates a temporary copy of the uploaded file in the xampp temp folder on the server (in this case, \\GOFLEX_HOME\GOFLEX HOME PUBLIC\xampp\tmp\). The temporary copy of the file disappears when the script ends. To store the uploaded file permanently, it is necessary to copy it to a different location. The $_FILES variable in the script is a PHP "superglobal", or automatic global variable, which means that it is available for any scope throughout the script. It represents an associative array of items that are uploaded to the current script using the HTTP POST method. The array elements used in the script are described below.

Because allowing users to upload files to the server is a potential minefield in terms of server security, it is a good idea to place some restrictions on the type or size of file that will be accepted. The following script restricts uploads to text files with a maximum size of 64 kilobytes.


<?php
if ($_FILES["file"]["type"] == "text/plain" &&
    $_FILES["file"]["size"] < 65536)
{
  if ($_FILES["file"]["error"] > 0)
  {
    echo "Error: " . $_FILES["file"]["error"] . "<br>";
  }
  else
  {
    echo "Upload: " . $_FILES["file"]["name"] . "<br>";
    echo "Type: " . $_FILES["file"]["type"] . "<br>";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br>";
    echo "Stored in: " . $_FILES["file"]["tmp_name"];
  }
}
else
{
  if ($_FILES["file"]["type"] != "text/plain")
    echo "File is not of the permitted type.";
  else if ($_FILES["file"]["size"] < 65536)
    echo "File exceeds permitted size.";
}
?>


Enter the code above into a text editor and save it with the filename "upload_02.php" in the "htdocs" directory of your "xampp" directory. Edit the <FORM> tag in the upload_01.html file to read as follows:


<form action="upload_02.php" . . . >


Save the file as "upload_02.html", start the XAMPP server, and type the following URL into the browser’s address bar:


http://localhost/upload_02.html


Using the Browse button, Select a file that is not a text file, and click on the submit button. You should see a web page that looks something like the screenshot below.


The output from upload_02.php

The output from upload_02.php


In order to save a permanent copy of the file on the server, we need to use the move_uploaded_file() function to create a copy of the uploaded file in a permanent storage location. Providing the file we are attempting to upload meets the specified size and type restrictions, and providing the file does not already exist on the server in the target directory, the following script will save the uploaded file to a named directory:


<?php
if ($_FILES["file"]["type"] == "text/plain" &&
    $_FILES["file"]["size"] < 65536)
{
  if ($_FILES["file"]["error"] > 0)
  {
    echo "Error: " . $_FILES["file"]["error"] . "<br>";
  }
  else
  {
    echo "Upload: " . $_FILES["file"]["name"] . "<br>";
    echo "Type: " . $_FILES["file"]["type"] . "<br>";
    echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br>";
    echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br>";
    if (file_exists("upload/" . $_FILES["file"]["name"]))
    {
      echo $_FILES["file"]["name"] . " already exists. ";
    }
    else
    {
      move_uploaded_file($_FILES["file"]["tmp_name"],
      "upload/" . $_FILES["file"]["name"]);
      echo "Saved as: " . "upload/" . $_FILES["file"]["name"];
    }
  }
}
else
{
  if ($_FILES["file"]["type"] != "text/plain")
    echo "File is not of the permitted type.";
  else if ($_FILES["file"]["size"] < 65536)
    echo "File exceeds permitted size.";
}
?>


Enter the code above into a text editor and save it with the filename "upload_03.php" in the "htdocs" directory of your "xampp" directory. Edit the <FORM> tag in the upload_01.html file to read as follows:


<form action="upload_03.php" . . . >


Save the file as "upload_03.html", start the XAMPP server, and type the following URL into the browser’s address bar:


http://localhost/upload_03.html


In order for the script to work, you will need to create a new folder called "upload" in the "htdocs" directory of your "xampp" directory. Once you have done this, use the Browse button to select a text file that has a file size of less than 64 kilobytes, and click on the Submit button. You should see a web page that looks something like the screenshot below.


The output from upload_03.php

The output from upload_03.php


Satisfy yourself that the script has indeed saved your chosen text file to the "upload" directory, and then reload the page. You should see a message saying that the file already exists.


You will see this output from upload_03.php if the file already exists

You will see this output from upload_03.php if the file already exists