In this tutorial we are going to learn about PHP Force File Download. it protects file for directly accessing file path. when user click on file link like whether it PDF, images or ZIP – PHP HEADERS helps force downloading file without opening links. This will helps for securing file like invoices or other sensitive information. We will explain in details about PHP download script and secure file download.
We can check if file exists on server using file_exists and use header(), readfile() function to easily achieve our download file goal.
PHP Force File Download Script
Below php download script tells browser to download file without preview it.
<?php $file = 'styled.pdf'; // File in the current directory if (file_exists($file)) { // Force file download using PHP headers header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($file) . '"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); // Flush and read the file flush(); readfile($file); exit; } else { echo "File not found."; }
Making PHP Download script secure.
basename functions helps for removing slashes and dots. if you where passing query string on browser it prevents directory traversal attacks.
$file=$_GET['file']; header('Content-Disposition: attachment; filename="' . basename($file) . '"');
Restrict file downloading.
allow only specific extension file. this will helps for give restriction file types download.
$allowed = ['pdf', 'zip', 'jpg']; $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if (!in_array($ext, $allowed)) { die("Invalid file type."); }
Large file uploading using chunk reading
Below example code chunked reading 1MB file to prevent memory overload and works for slow connections.
<?php $file = 'styled.pdf'; // File in the current directory if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($file) . '"'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); // Clean output buffer before reading file ob_clean(); flush(); // Read the file in chunks (1MB at a time) $chunkSize = 1024 * 1024; // 1MB $handle = fopen($file, 'rb'); while (!feof($handle)) { echo fread($handle, $chunkSize); flush(); // Push to browser } fclose($handle); exit; } else { http_response_code(404); echo "File not found."; }