File Download Script in PHP | PHP Tutorial For Beginners

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-Type from 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.

← Older Post Newer Post →