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 in 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 files 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 a sub-directory called uploads to store uploaded files

Uploading File In PHP

Let’s create a PHP file to start the program. Open your text editor or IDE and create a new file called index.php or you can give a name as per your preferences. Open that file and place the 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 a 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 the 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'])) {
    // Retrieve file information
    $filename = $_FILES['m_file']['name'];
    $destination = 'uploads/' . $filename;
    $extension = pathinfo($filename, PATHINFO_EXTENSION);
    $file = $_FILES['m_file']['tmp_name'];
    $size = $_FILES['m_file']['size'];

    // Check if the file type is allowed
    if (!in_array($extension, ['png', 'jpg', 'ico', 'zip', 'pdf', 'docx'])) {
        echo "Invalid File Type";
    } else {
        // Move the uploaded file to the specified destination
        if (move_uploaded_file($file, $destination)) {
            // Insert file details into the database
            $sql = "INSERT INTO files (name, size, downloads) VALUES ('$filename', $size, 0)";
            if (mysqli_query($conn, $sql)) {
                echo "File uploaded successfully";
            } else {
                echo "Failed to upload file";
            }
        } else {
            echo "Failed to move file to destination";
        }
    }
}
?>

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

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

Lastly, we added the record to our files table. It will store file size and file name. In any case, the script faces an error while moving the uploaded file we 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 the form with single input and when you select a file and submit the form, it will store the selected file on a server. It will also create a record in the files table. Right now you can check it using phpMyAdmin.

Downloading files in PHP

After adding some files, we can now 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 the 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 the files table and print it into a table. In the action column, we have created a URL for the same page with the 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 the files table and then create a path using name value. Here, we have set some headers for files and started downloading files.

At last, we perform an update query and increase the download count to the 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 listings, and download files one by one as per your requirement. For further improvement or learning purposes, you can configure file storage structures like file managers or perform delete and move action-based.