How to download or upload file in PHP

Nowadays, File upload and download functionality is almost mandatory. PHP provides simple and easy ways to upload and download files. You can store these files in a public folder or local storage.

In this tutorial, we will show you how you can upload files of various formats like .zip, .pdf, .docx, and .ppt, as well as image files through a form using PHP to be stored in a folder on our server. Here, we will also store file information like name, size and time to our database.

Before starting let's create a table in your database using the below query. In this table, we will store information about uploaded file and manage download counts by this table.

CREATE TABLE IF NOT EXISTS `files` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `size` int(11) NOT NULL,
  `downloads` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
);

Let's start our article by creating a new directory in our localhost by fileUploadDownload. Here, we will also use sub-directory called uploads to store uploaded files

Uploading File In PHP

Let's create a PHP file to start out the program. Open your text editor or IDE and create new file called index.php or you can give name as per your preferences. Open that file and place below code:

<?php include 'fileOperations.php';?>
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Files Upload and Download Example in PHP</title>
    <style type="text/css">
        form {
          width: 30%;
          margin: 100px auto;
          padding: 30px;
          border: 1px solid #555;
        }
        input {
          width: 100%;
          border: 1px solid #f1e1e1;
          display: block;
          padding: 5px 10px;
        }
        button {
          border: none;
          padding: 10px;
          border-radius: 5px;
        }
        table {
          width: 60%;
          border-collapse: collapse;
          margin: 100px auto;
        }
        th,
        td {
          height: 50px;
          vertical-align: center;
          border: 1px solid black;
        }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="row">
        <form action="index.php" method="post" enctype="multipart/form-data" >
          <h3>Upload File</h3>
          <input type="file" name="m_file"> <br>
          <button type="submit" name="save">upload</button>
        </form>
      </div>
    </div>
  </body>
</html>

Here, we just created a form with single input as file type and the action of this form is self. For handling form action we have included fileOperations.php.

The fileOperations.php will handle all operations related to file upload and downloads. Open file and make the following changes to it:

<?php
    // database connection
    $conn = mysqli_connect('localhost', 'USERNAME', 'PASSWORD', 'DATABASE_NAME');

    // Uploads files
    if (isset($_POST['save'])) { // handles save
        $filename = $_FILES['m_file']['name'];

        $destination = 'uploads/' . $filename;

        // gets file extension
        $extension = pathinfo($filename, PATHINFO_EXTENSION);

        $file = $_FILES['m_file']['tmp_name'];
        $size = $_FILES['m_file']['size'];

        if (!in_array($extension, ['png','jpg','ico','zip', 'pdf', 'docx'])) {
            echo "Invalid File Type";
        }else {
            // move the uploaded (temporary) file to the specified destination
            if (move_uploaded_file($file, $destination)) {
                $sql = "INSERT INTO files (name, size, downloads) VALUES ('$filename', $size, 0)";
                if (mysqli_query($conn, $sql)) {
                    echo "File uploaded successfully";
                }
            } else {
                echo "Something went wrong while uploading file.";
            }
        }
    }
?>

In the above example, first of all we are connecting to database using credentials. Then we fetch an extension from file and validate it against some predefined extensions.

We have used move_uploaded_file() function to store uploaded file in our uploads directory. It will take two parameters first one is file and the second is storage location.

Lastly, we added record into our files table. It will stores file size and file name. In any case, script face error while moving the uploaded file we simply print an error message.

Now you can test file upload functionality by executing index.php file in your browser. Open your browser and enter below url:

http://localhost/fileUploadDownload/index.php.

Here, it will show form with single input and when you select file and submit the form then it will store the selected file on a server. It will also create record in files table. Right now you can check it using phpMyAdmin.

Downloading File In PHP

After adding some files, now we can start downloading functionality. Let's create a new file called downloads.php in our root directory. It will contain a simple table which will show a listing of files.

Open downloads.php file and modify it as below:

<?php include 'fileOperations.php';?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Download files</title>
    </head>
    <body>
        <table>
            <thead>
                <th>ID</th>
                <th>File Name</th>
                <th>Size</th>
                <th>Downloads</th>
                <th>Action</th>
            </thead>
            <tbody>
                <?php foreach ($files as $file): ?>
                <tr>
                    <td><?php echo $file['id']; ?></td>
                    <td><?php echo $file['name']; ?></td>
                    <td><?php echo floor($file['size'] / 1000) . ' KB'; ?></td>
                    <td><?php echo $file['downloads']; ?></td>
                    <td><a href="downloads.php?id=<?php echo $file['id'] ?>">Download</a></td>
                </tr>
                <?php endforeach;?>
            </tbody>
        </table>
    </body>
</html>

Let's create logic to perform a download using action button. Open filesLogic.php and append below code into it:

...
...

//Fetch data for table
$sql = "SELECT * FROM files";
$result = mysqli_query($conn, $sql);

$files = mysqli_fetch_all($result, MYSQLI_ASSOC);

//Handles Download Oeration
if (isset($_GET['id'])) {
    $id = $_GET['id'];

    // fetch file to download from database
    $sql = "SELECT * FROM files WHERE id=$id";
    $result = mysqli_query($conn, $sql);

    $file = mysqli_fetch_assoc($result);
    $filepath = 'uploads/' . $file['name'];

    if (file_exists($filepath)) {
        header('Content-Description: File Transfer');
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename=' . basename($filepath));
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize('uploads/' . $file['name']));
        readfile('uploads/' . $file['name']);

        // Now update downloads count
        $newCount = $file['downloads'] + 1;
        $updateQuery = "UPDATE files SET downloads=$newCount WHERE id=$id";
        mysqli_query($conn, $updateQuery);
        exit;
    }
}

First of all, we fetch all data from files table and print it into table. In the action column, we have created a URL for the same page with table id as a parameter. So it will create a unique link for the file. When the user clicks on that link it will start implementing download logic.

In Download logic, first of all we will find records from files table and then create path using name value. Here, we have set some headers for files and started downloading file.

At last, we perform an update query and increase download count to files table against a particular file.

Conclusion

In this article, we have created file upload and download functionality in PHP where users can upload a file, see all file listing,s and download files one by one as per your requirement. In further improvement or learning purposes, you can configure file storage structures like file managers or perform delete and move action-based.