File download consists of front-end GUI and back-end code .
Caution: Never use include or require for uploaded files. Serve them as static or use file_get_contents(), readfile() etc.
Standard GUIAdvanced GUIBack-end
Standard Front-end Page
The Download form sends GET request to the back-end.
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> div.form { padding: 0.5rem 2rem 0; background-color: #eee; line-height: 1.8rem; } </style> </head> <body> <div class="form"> <div>File Download Form</div> <label>Download using link:</label><br /> <a href="download_handler.php?download=flowers.jpg">flowers.jpg</a><br /> <label>Download using javascript:</label><br /> <button onclick="download(this)">flowers.jpg</button> </div> <script> function download(btn){ var fileName = btn.innerHTML; window.location = 'download_handler.php?download=' + fileName; }; </script> </body> </html>
Standard GUI Demo
The Download form may send GET or POST request to the server.
Click on button on link to download file
Advanced Front-end Page
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style> .download-form { padding: 0.5rem 2rem 0.5rem; background-color: #eee; line-height: 1.8rem; float:left; } .download-form-img { width: 80px; display: block; margin: 0 auto; cursor: pointer; } .download-form-floated { float: left; text-align: center; padding:0.5rem; } .download-form-floated::after { content: ''; clear:both; } .download-form-file-list { margin-left: -0.5rem; } </style> </head> <body> <div class="download-form"> <div style="font-weight:700;">File List Form</div> <label>Get files list then click to download:</label><br /> <button onclick="get_list()">Get File List</button> <div class="download-form-file-list"></div> </div> <script> function send_get_request(url, callback) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { callback(this); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); } function get_list() { var file_list = document.getElementsByClassName('download-form-file-list')[0]; file_list.innerHTML = ''; send_get_request("list_handler.php?list=all", function(result){ var myObj = JSON.parse(result.responseText); for(var i in myObj) { var file_name = myObj[i]; add_file_btn(file_list,file_name); } }); } function add_file_btn(file_list,file_name) { var file_div = document.createElement("DIV"); file_div.className = "download-form-floated"; file_list.appendChild(file_div); var file_img = document.createElement("IMG"); file_img.className = "download-form-img"; file_div.appendChild(file_img); file_img.src = "list_handler.php?list=" + file_name; var file_cap = document.createElement("DIV"); file_cap.innerHTML = file_name; file_div.appendChild(file_cap); file_img.onclick = function() { window.location = 'download_handler.php?download=' + file_name; } } </script> </body> </html>
Advanced GUI Demo
code here
Download Handler
<?php $downloadDir = './downloads'; require_once "FileDownloader.php"; new FileDownloader($downloadDir);
List Handler
<?php //query download directory $downloadsPath = './downloads'; $thumbsDir = 'thumbs'; if (isset($_GET['list'])) { if ($_GET['list'] === 'all') { //get sorted file array and filter '..' and '.' $files = array_diff(scandir($downloadsPath), array('..', '.', $thumbsDir)); //return filenames to front-end as json echo json_encode($files); } else { $fileName = filter_var($_GET['list'],FILTER_SANITIZE_FULL_SPECIAL_CHARS); //replace non-image filenames with avatars if (substr($fileName,-4)=='.pdf') { $fileName = "pdf.png"; } $filePath = "$downloadsPath/$thumbsDir/$fileName"; //return thumbs jpg or png if (file_exists($filePath)) { @readfile($filePath); } } }
Download Class
<?php class FileDownloader { function __construct($downloadDir = '.') { if (isset($_GET['download'])) { $fileName = filter_var($_GET['download'],FILTER_SANITIZE_FULL_SPECIAL_CHARS); $this->do_download("$downloadDir/$fileName"); } } private function do_download($filePath) { //check if file exists if (!file_exists($filePath)) { echo "File named <b>$filePath</b> does not exist."; return; } //get mime type from file name extension $fileExt = strtolower(substr(strrchr($filePath,"."),1)); switch ($fileExt) { case "pdf": $mime="application/pdf"; break; case "exe": $mime="application/octet-stream"; break; case "zip": $mime="application/zip"; break; case "doc": $mime="application/msword"; break; case "xls": $mime="application/vnd.ms-excel"; break; case "ppt": $mime="application/vnd.ms-powerpoint"; break; case "gif": $mime="image/gif"; break; case "png": $mime="image/png"; break; case "jpe": case "jpeg": case "jpg": $mime="image/jpg"; break; default: $mime="application/force-download"; } //send headers and file contents header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: private",false); header("Content-Type: $mime"); header("Content-disposition: attachment; fileName=\"". basename($filePath) ."\""); header("Set-Cookie: fileDownload=true; path=/ "); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . @filesize($filePath)); set_time_limit(0); @readfile($filePath); exit; } }