File Download In PHP. Here’s How To Do It

Posted by TotalDC

Last time we talked about how you can upload file using PHP and in this tutorial, you will learn about file download in PHP.

How To Download Files in PHP

You don’t necessarily need to use any server-side language like PHP to download files if they are stored in an accessible folder you can create a hyperlink pointing to that file and when a user clicks on that link browser will automatically download that file.

<a href="downloads/test.zip">Download Zip file</a>
<a href="downloads/sample.jpg">Download Image file</a>
<a href="downloads/setup.exe">Download EXE file</a>
<a href="downloads/masters.pdf">Download PDF file</a>

When clicking a link that points to a PDF or an image file will not cause it to download to your hard drive directly. That will only open the file in your browser.

How To Download Files in PHP

You can download it directly to your hard drive using PHP’s readfile() function. In the next example, you will see a simple image gallery that allows users to download the image files.

Let’s create a file named “image-gallery.php”.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Simple Image Gallery</title>
<style type="text/css">
    .img-box{
        display: inline-block;
        text-align: center;
        margin: 0 15px;
    }
</style>
</head>
<body>
    <?php
    // Array containing sample image file names
    $images = array("cats.jpg", "dogs.jpg");
    
    // Loop through array to create image gallery
    foreach($images as $image){
        print '<div class="img-box">';
            print '<img src="images/' . $image . '" width="200" alt="' .  pathinfo($image, PATHINFO_FILENAME) .'">';
            print '<p><a href="download.php?file=' . urlencode($image) . '">Download</a></p>';
        print '</div>';
    }
    ?>
</body>
</html>

In this example, you will find that the download link points to a download.php file and the URL contains the image file name as a query string. Also, there is urlencode() function to encode the image file names so that it can be safely passed as a URL parameter.

Here is the complete code of download.php file:

<?php
if(isset($_REQUEST["file"])){
    // Get parameters
    $file = urldecode($_REQUEST["file"]); // Decode URL-encoded string

    /* Test whether the file name contains illegal characters
    such as "../" using the regular expression */
    if(preg_match('/^[^.][-a-z0-9_.]+[a-z]$/i', $file)){
        $filepath = "images/" . $file;

        // Process download
        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($filepath));
            flush(); // Flush system output buffer
            readfile($filepath);
            die();
        } else {
            http_response_code(404);
	        die();
        }
    } else {
        die("Invalid file name!");
    }
}
?>

The regular expression in the above example (line no-8) will simply not allow those files whose name starts or ends with a dot character (.), for example, cats.jpg, dogs.jpg etc.