This tutorial demonstrates how you can upload files of various formats including .zip, .pdf, .docx, .ppt, as well as image files through a form using PHP to be stored in a folder on our server.
We will also record the name of the uploaded files and related info such as the file name, size, and the number of downloads in a database table.
Create a new PHP project folder and call it file-upload-download. Create a subfolder inside this folder called uploads (this is where our uploaded files will be stored), and a file called index.php.
index.php is where we will create our file upload form. Open it and put this code inside it:
ez_adindex.php:
<?php include 'filesLogic.php';?>
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css">
<title>Files Upload and Download</title>
</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="myfile"> <br>
<button type="submit" name="save">upload</button>
</form>
</div>
</div>
</body>
</html>
It's a very simple form that takes just the input field for our file and an upload button.
In the head section, we are linking to our style.css file to provide some styling to our form. Create that file in the root of our application and add this CSS code to it:
style.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;
}
vli_ad
At the top of index.php, we are including filesLogic.php file. This is the file that contains all the logic of receiving our submitted file and saving it to the uploads folder as well as storing the file information in the database. Let's create this file now.
filesLogic.php:
<?php
// connect to the database
$conn = mysqli_connect('localhost', 'root', '', 'file-management');
// Uploads files
if (isset($_POST['save'])) { // if save button on the form is clicked
// name of the uploaded file
$filename = $_FILES['myfile']['name'];
// destination of the file on the server
$destination = 'uploads/' . $filename;
// get the file extension
$extension = pathinfo($filename, PATHINFO_EXTENSION);
// the physical file on a temporary uploads directory on the server
$file = $_FILES['myfile']['tmp_name'];
$size = $_FILES['myfile']['size'];
if (!in_array($extension, ['zip', 'pdf', 'docx'])) {
echo "You file extension must be .zip, .pdf or .docx";
} elseif ($_FILES['myfile']['size'] > 1000000) { // file shouldn't be larger than 1Megabyte
echo "File too large!";
} 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 "Failed to upload file.";
}
}
}
At the top of this file, we are connecting to a database but we've not yet created it yet. Let's do that now.
vli_adCreate a new database called file-management. Under this database, create a table called files and give it the following fields.
- id - INT
- name - VARCHAR(255)
- size - INT
- downloads
Now open index.php file in your browser. For me, I'll head over to http://localhost/file-upload-download/download.php.
Click on the file input field and select any file from your machine to upload.
Note: Depending on your php configuration, your file may fail to upload if the size exceeds the upload_max_filesize value set in your php.ini file. You can always configure this info in your php.ini file. Increase the values of post_max_size and upload_max_filesize .
Having selected your file, you can click on the upload button. If everything goes well, your file will be uploaded to the uploads folder in your project and a new record will be created in the files table in the database containing the filename, size, and downloads count.
Now our file has been uploaded. You can check your uploads folder and database table to confirm that it was successful. Let's display it so that the user can view it and click on it to download it. First, we need to fetch the file info from the database.
Open filesLogic.php and add these 3 lines of code just below the line where we connect to the database:
<?php
// connect to database
$conn = mysqli_connect('localhost', 'root', '', 'file-management');
$sql = "SELECT * FROM files";
$result = mysqli_query($conn, $sql);
$files = mysqli_fetch_all($result, MYSQLI_ASSOC);
This selects all files information from the database and sets it to an array variable called $files.
ez_adNow create a file called downloads.php in the root folder of our application and add this code inside it:
downloads.php:
<?php include 'filesLogic.php';?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="style.css">
<title>Download files</title>
</head>
<body>
<table>
<thead>
<th>ID</th>
<th>Filename</th>
<th>size (in mb)</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?file_id=<?php echo $file['id'] ?>">Download</a></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</body>
</html>
Now on this page, the files information from the database are listed each along with its size in KB and number of downloads. There is also a download button against each file. What remains now is the code that actually downloads the file from our uploads folder. Let's write the code right away.
Open filesLogic.php again and add this code at the end of the file:
filesLogic.php:
// Downloads files
if (isset($_GET['file_id'])) {
$id = $_GET['file_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;
}
}
ez_ad
When we were listing the files, each download button (or rather, download link) had a parameter called file_id attached to it. So when you click on the download link of a file, that file's id is sent to the filesLogic.php page and is grabbed by this piece of code we just added now.
The code then fetches that particular file info from the database using the file_id parameter and then stores the file info in a variable called $file. Using PHP's file_exists() method with the full path to our file as an argument we check that the file actually exists in our uploads folder. Then we proceed to set some headers and finally respond with the file to the user using the readFile() function in PHP.
After the file is downloaded, we update the downloads count for that particular file in the database.
Conclusion
That's about it with file upload and download. You can further customize it to build cool PHP applications. Thanks very much for following. Let me know what you think about this article in the comments section below, if you please.
Have a nice time!
Awa Melvine
ez_ad