This tutorial shows how to force-download any file stored on your web server to the user's local machine. The file name is passed as a query string parameter, and a reusable download_file() function handles MIME type detection and the correct HTTP headers.
Step 1 — HTML Download Links (index.html)
Create a page with download links. Each link points to download.php and passes the file name as a query string value. The actual files must live inside a files/ folder on the server.
<html>
<head>
<title>File download in PHP</title>
</head>
<body>
<table>
<tr>
<td>
<a href="download.php?file=download_file_in_php.jpg">
Download image
</a>
</td>
</tr>
<tr>
<td>
<a href="download.php?file=file_download.pdf">
Download PDF
</a>
</td>
</tr>
</table>
</body>
</html>
Step 2 — Download Handler (download.php)
This script reads the file name from the query string, builds the path inside files/, auto-detects the MIME type, and streams the file to the browser with the appropriate headers.
<?php
set_time_limit(0);
// Path to the file — all downloadable files must be in this folder
$file_path = 'files/' . $_REQUEST['file'];
// Call the download function with path, name, and MIME type
download_file($file_path, $_REQUEST['file'], 'text/plain');
function download_file($file, $name, $mime_type = '')
{
if (!is_readable($file)) die('File not found.');
$size = filesize($file);
$name = rawurldecode($name);
// MIME type map
$known_mime_types = array(
"pdf" => "application/pdf",
"txt" => "text/plain",
"html" => "text/html",
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"png" => "image/png",
"jpeg" => "image/jpg",
"jpg" => "image/jpg",
"php" => "text/plain"
);
// Auto-detect MIME type from extension if not supplied
if ($mime_type == '') {
$file_extension = strtolower(substr(strrchr($file, "."), 1));
if (array_key_exists($file_extension, $known_mime_types)) {
$mime_type = $known_mime_types[$file_extension];
} else {
$mime_type = "application/force-download";
}
}
@ob_end_clean();
// Required for IE — disable zlib compression
if (ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="' . $name . '"');
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
header('Cache-control: private');
header('Pragma: private');
readfile($file);
}
?>
How It Works
$_REQUEST['file']— receives the file name from the query string.is_readable($file)— checks the file exists before proceeding.- The MIME type map auto-detects the correct
Content-Typefrom the file extension. Content-Disposition: attachment— forces the browser to download rather than display the file.readfile($file)— streams the file contents directly to the browser.
Hope this tutorial is useful for you. Keep following PHP Tutorial for Beginners for more help.