PHP – Use Case 3: Creating a File Upload and Management System
Project Overview
A File Upload and Management System allows users to upload, view, download, and delete files. This project involves handling file uploads securely, storing file information in a database, and managing user interactions with the files using PHP and MySQL.
Prerequisites
Ensure you have the following:
- Web Server: Apache (using XAMPP, WAMP, or MAMP)
- PHP: Version 7.4 or higher
- MySQL: For database management
- Code Editor: VS Code, Sublime Text, PHPStorm, etc.
- Composer: For dependency management (optional)
Step-by-Step Procedure
1. Setting Up the Development Environment
- Install XAMPP:
- Download from XAMPP Official Website.
- Follow the installation wizard and install it in the default directory.
- Start Apache and MySQL:
- Open the XAMPP Control Panel.
- Start the Apache and MySQL modules.
2. Creating the Database
- Access phpMyAdmin:
- Navigate to
http://localhost/phpmyadmin/
in your browser.
- Navigate to
- Create a New Database:
- Click on “New” in the left sidebar.
- Name the database
file_manager
. - Choose “utf8mb4_unicode_ci” as the collation.
- Click “Create”.
- Create a
files
Table:- Select the
file_manager
database. - Click on “New” to create a table.
- Define the table with the following fields:
- Click “Save”.
- Select the
3. Project Structure
Organize your project files as follows:
file-manager/
├── uploads/ # Directory to store uploaded files
├── assets/
│ ├── css/
│ │ └── styles.css
│ └── js/
│ └── scripts.js
├── config/
│ └── db.php
├── templates/
│ ├── header.php
│ └── footer.php
├── upload.php
├── view_files.php
├── download.php
├── delete_file.php
└── README.md
Note: Ensure that the uploads/
directory is writable by the web server.
4. Configuration
a. Database Connection (config/db.php
)
<?php
// config/db.php
$host = 'localhost';
$db = 'file_manager';
$user = 'root'; // Default XAMPP MySQL user
$pass = ''; // Default XAMPP MySQL password is empty
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // Enable exceptions
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, // Fetch associative arrays
PDO::ATTR_EMULATE_PREPARES => false, // Disable emulation
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
} catch (\PDOException $e) {
// Handle connection errors
throw new \PDOException($e->getMessage(), (int)$e->getCode());
}
?>
5. Creating Reusable Templates
a. Header (templates/header.php
)
<?php
// templates/header.php
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>File Upload and Management System</title>
<link rel="stylesheet" href="/file-manager/assets/css/styles.css">
</head>
<body>
<header>
<h1>File Upload and Management System</h1>
<nav>
<a href="/file-manager/upload.php">Upload File</a>
<a href="/file-manager/view_files.php">View Files</a>
</nav>
</header>
<main>
b. Footer (templates/footer.php
)
<?php
// templates/footer.php
?>
</main>
<footer>
<p>© <?php echo date("Y"); ?> Your Company Name</p>
</footer>
<script src="/file-manager/assets/js/scripts.js"></script>
</body>
</html>
6. Styling the Application (assets/css/styles.css
)
Add basic styles to enhance the appearance.
/* assets/css/styles.css */
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
}
header, footer {
background-color: #555;
color: #fff;
padding: 10px 20px;
}
header h1, footer p {
margin: 0;
}
nav a {
color: #fff;
margin-right: 15px;
text-decoration: none;
}
main {
padding: 20px;
}
form {
max-width: 500px;
margin: auto;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
}
input[type="file"],
input[type="text"] {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
button {
padding: 10px 15px;
background-color: #28a745;
color: #fff;
border: none;
cursor: pointer;
}
button:hover {
background-color: #218838;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
table, th, td {
border: 1px solid #ddd;
}
th, td {
padding: 12px;
text-align: left;
}
th {
background-color: #f4f4f4;
}
a {
color: #007BFF;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
.error {
background-color: #f2dede;
color: #a94442;
padding: 15px;
margin-bottom: 20px;
border: 1px solid #ebccd1;
border-radius: 4px;
}
.success {
background-color: #dff0d8;
color: #3c763d;
padding: 15px;
margin-bottom: 20px;
border: 1px solid #d6e9c6;
border-radius: 4px;
}
7. Implementing File Upload (upload.php
)
This page allows users to upload files to the server.
<?php
// upload.php
require 'config/db.php';
require 'templates/header.php';
$errors = [];
$success = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// Check if file was uploaded without errors
if (isset($_FILES['file']) && $_FILES['file']['error'] === UPLOAD_ERR_OK) {
$fileTmpPath = $_FILES['file']['tmp_name'];
$originalName = $_FILES['file']['name'];
$fileSize = $_FILES['file']['size'];
$fileType = $_FILES['file']['type'];
$fileNameCmps = explode(".", $originalName);
$fileExtension = strtolower(end($fileNameCmps));
// Sanitize file name
$newFileName = md5(time() . $originalName) . '.' . $fileExtension;
// Allowed file extensions
$allowedfileExtensions = ['jpg', 'gif', 'png', 'txt', 'xls', 'doc', 'pdf'];
if (in_array($fileExtension, $allowedfileExtensions)) {
// Directory in which the uploaded file will be moved
$uploadFileDir = './uploads/';
$dest_path = $uploadFileDir . $newFileName;
if(move_uploaded_file($fileTmpPath, $dest_path))
{
// Insert file info into database
$uploaded_by = 'Admin'; // Replace with dynamic user info if applicable
$stmt = $pdo->prepare('INSERT INTO files (filename, filepath, uploaded_by) VALUES (?, ?, ?)');
if ($stmt->execute([$originalName, $newFileName, $uploaded_by])) {
$success = 'File is successfully uploaded.';
} else {
$errors[] = 'There was an error saving the file information to the database.';
}
}
else
{
$errors[] = 'There was an error moving the uploaded file.';
}
}
else
{
$errors[] = 'Upload failed. Allowed file types: ' . implode(',', $allowedfileExtensions);
}
}
else
{
$errors[] = 'There is some error in the file upload. Please check the following error.<br>';
$errors[] = 'Error:' . $_FILES['file']['error'];
}
}
?>
<h2>Upload File</h2>
<?php if (!empty($errors)): ?>
<div class="error">
<ul>
<?php foreach($errors as $error): ?>
<li><?php echo htmlspecialchars($error); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php if ($success): ?>
<div class="success">
<p><?php echo htmlspecialchars($success); ?></p>
</div>
<?php endif; ?>
<form action="upload.php" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label for="file">Choose File:</label>
<input type="file" id="file" name="file" required>
</div>
<button type="submit">Upload</button>
</form>
<?php
require 'templates/footer.php';
?>
8. Viewing Uploaded Files (view_files.php
)
This page lists all uploaded files with options to download or delete them.
<?php
// view_files.php
require 'config/db.php';
require 'templates/header.php';
// Fetch all files
$stmt = $pdo->query('SELECT * FROM files ORDER BY uploaded_at DESC');
$files = $stmt->fetchAll();
?>
<h2>Uploaded Files</h2>
<?php if ($files): ?>
<table>
<thead>
<tr>
<th>ID</th>
<th>Filename</th>
<th>Uploaded By</th>
<th>Uploaded At</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<?php foreach ($files as $file): ?>
<tr>
<td><?php echo htmlspecialchars($file['id']); ?></td>
<td><?php echo htmlspecialchars($file['filename']); ?></td>
<td><?php echo htmlspecialchars($file['uploaded_by']); ?></td>
<td><?php echo htmlspecialchars($file['uploaded_at']); ?></td>
<td>
<a href="download.php?id=<?php echo $file['id']; ?>">Download</a> |
<a href="delete_file.php?id=<?php echo $file['id']; ?>" onclick="return confirm('Are you sure you want to delete this file?');">Delete</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p>No files uploaded yet.</p>
<?php endif; ?>
<?php
require 'templates/footer.php';
?>
9. Downloading Files (download.php
)
This script handles the downloading of files.
<?php
// download.php
require 'config/db.php';
// Get file ID from URL
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// Fetch file details
$stmt = $pdo->prepare('SELECT * FROM files WHERE id = ?');
$stmt->execute([$id]);
$file = $stmt->fetch();
if ($file) {
$filePath = './uploads/' . $file['filepath'];
if (file_exists($filePath)) {
// Set headers
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file['filename']).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filePath));
// Clear output buffer
ob_clean();
flush();
// Read the file
readfile($filePath);
exit;
} else {
echo "<p>File not found.</p>";
}
} else {
echo "<p>Invalid file ID.</p>";
}
?>
10. Deleting Files (delete_file.php
)
This script handles the deletion of files from both the server and the database.
<?php
// delete_file.php
require 'config/db.php';
// Get file ID from URL
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
// Fetch file details
$stmt = $pdo->prepare('SELECT * FROM files WHERE id = ?');
$stmt->execute([$id]);
$file = $stmt->fetch();
if ($file) {
$filePath = './uploads/' . $file['filepath'];
// Delete file from server
if (file_exists($filePath)) {
unlink($filePath);
}
// Delete from database
$stmt = $pdo->prepare('DELETE FROM files WHERE id = ?');
$stmt->execute([$id]);
// Redirect to view files page
header('Location: view_files.php');
exit;
} else {
echo "<p>Invalid file ID.</p>";
}
?>
11. Testing the Application
- Access the Upload Page:
- Navigate to
http://localhost/file-manager/upload.php
. - Upload a file and submit.
- Verify that the file appears in the
uploads/
directory and is listed on the “View Files” page.
- Navigate to
- View Uploaded Files:
- Navigate to
http://localhost/file-manager/view_files.php
. - Ensure all uploaded files are listed with options to download or delete.
- Navigate to
- Download a File:
- Click on “Download” next to a file.
- Verify that the file is downloaded correctly.
- Delete a File:
- Click on “Delete” next to a file.
- Confirm the deletion.
- Ensure the file is removed from both the server and the database.
12. Deployment Considerations
When deploying to a live server:
- Secure the
uploads/
Directory:- Prevent direct access to uploaded files by using
.htaccess
to restrict access or store files outside the web root.
.htaccess
to Deny Access:# Deny access to all files Deny from all
- Prevent direct access to uploaded files by using
- Validate File Types and Sizes:
- Strictly enforce allowed file types and size limits to prevent malicious uploads.
- Use HTTPS:
- Ensure your website uses HTTPS for encrypted data transmission.
- Regular Backups:
- Implement regular backups of your database and uploaded files.
- Error Reporting:
- Disable detailed error messages in production to prevent information leakage.
// In production, set error reporting to minimal ini_set('display_errors', 0); ini_set('log_errors', 1);
- Update Dependencies:
- Keep PHP and all libraries updated to their latest versions to patch security vulnerabilities.