{"id":835,"date":"2012-10-15T08:41:58","date_gmt":"2012-10-15T08:41:58","guid":{"rendered":"http:\/\/faq.pctrickers.com\/?p=835"},"modified":"2023-03-27T15:20:20","modified_gmt":"2023-03-27T15:20:20","slug":"php-force-download-a-file-example","status":"publish","type":"post","link":"https:\/\/webexplorar.com\/php-force-download-a-file-example\/","title":{"rendered":"PHP force download a file example"},"content":{"rendered":"<p>PHP allows you to change the <strong>HTTP Headers<\/strong> of files that you&#8217;re writing, so that you can <strong>force a file to be downloaded<\/strong> that normally the browser would load in the same window.<br \/>\nFollowing <strong>php script will give to force download a file using php<\/strong>.<br \/>\n<!--more--><\/p>\n<pre class=\"lang:php decode:true \">\n<?php\n\/\/ get the requested file's name\n$file_name = $_GET['file'];\n\/\/ make sure it's a file before doing anything!\nif(is_file($file_name)) {\n\t\/*\n\t\tYou can check user permissions here  or\n\t\tfile download times\/counter\n\t*\/\n\t\/\/ required for IE\n\tif(ini_get('zlib.output_compression')) {\n\t\tini_set('zlib.output_compression', 'Off');\n\t}\n\t\/\/ get the file Mime type using the file extension\n\tswitch(strtolower(substr(strrchr($file_name, '.'), 1))) {\n\t\tcase 'pdf':  $mime = 'application\/pdf'; break; \/\/ pdf files\n\t\tcase 'zip':  $mime = 'application\/zip'; break; \/\/ zip files\n\t\tcase 'jpeg': $mime = 'image\/jpeg'; break;\/\/ images jpeg\n\t\tcase 'jpg':  $mime = 'image\/jpg'; break;\n\t\tcase 'mp3':  $mime = 'audio\/mpeg'; break; \/\/ audio mp3 formats\n\t\tcase 'doc':  $mime = 'application\/msword'; break; \/\/ ms word\n\t\tcase 'avi':  $mime = 'video\/x-msvideo'; break;  \/\/ video avi format\n\t\tcase 'txt':  $mime = 'text\/plain'; break; \/\/ text files\n\t\tcase 'xls':  $mime = 'application\/vnd.ms-excel'; break; \/\/ ms excel\n\t\tdefault: $mime = 'application\/force-download';\n\t}\n\theader('Pragma: public'); \t\/\/ required\n\theader('Expires: 0');\t\t\/\/ no cache\n\theader('Cache-Control: must-revalidate, post-check=0, pre-check=0');\n\theader('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($file_name)).' GMT');\n\theader('Cache-Control: private',false);\n\theader('Content-Type: '.$mime);\n\theader('Content-Disposition: attachment; filename=\"'.basename($file_name).'\"');\n\theader('Content-Transfer-Encoding: binary');\n\theader('Content-Length: '.filesize($file_name));\t\/\/ provide file size\n\theader('Connection: close');\n\treadfile($file_name);\n\texit();\n}\n?>\n<\/pre>\n<p>The MIME(Multipurpose Internet Mail Extensions) specifications only described the structure of mail messages.You can read about the MIME type from this link.<br \/>\nSome peoples may be argue that attackers can be download index.php, header.php such db connection files.But above <strong>switch statement<\/strong> is checking that you want to download file type.So it is secure.<\/p>\n<h3>How to use this?<\/h3>\n<p><code><br \/>\nhref=\"domainName\/downloadFile.php?file=Students_Marks.pdf\"<br \/>\n<\/code><br \/>\n<strong>Note:-Sometimes your file will get an error as follows.<\/strong><br \/>\n<code>Warning: Cannot modify header information - headers already sent by (output started......<br \/>\n%PDF-1.3 %\u00e2\u00e3??\u00d3 1 0 obj << \/Filter[\/FlateDecode] \/Length 750 >> stream X\u2026\u001d\u2018??O\u00d3p@o\u00ea\u2022\u0192???\u00c0\u000fv\u2019 \u02dc\u00d5?\u0010\u00d8g\u203a@bY\u00b7\u00b2\u00c4\u0192\u2122k\u00bbE\u0011d\u00eb\u00af0\u201a??\u0152\u00b6 L\u00a6\u0019]\u00bb\u0011#\u0007\u00b6n|D!e\u00b0 11???&\u001e4\u2022\u00e0X\u00e2\u00c5\u0178zp\u00c7]%\u00be\u00e4??_\u00f2ln\u00c2N\u0011W\u00d1\u00feK\u00c8??V\u00b3? ]]N\u00d7\u2026\u001b\u001d\u0017\u00bb:\u00ae\u00da\u00ccF\u001c\u00a3\u0001\u00e5\u00a2)\u00c4\u00d3\u00e7\"??\u0014M\u00fby\u00ca??\u0002\u2020\u000f\u000fF\u2020\u0192BLX\u00fcx\u00ff\u00b9\u00dc\u00e9\u00a60\u2019\u2013\u00d2Z\u00f5\u00f8W~G\u001fx*\u00b6\u00a2\u000f\u00dap\u00a7\u00c9\u00cb\u00d8)@\u00f8\u00d9\u00ee'\u201a?\u00dc\u00c8j\u2022B\u00be\u00f2I\u00af\u00c3\u0006\u201e\u00ff=\u2026Nj?\u2022\u00b5\u00bd\u00f1\u00d4\u00ee\u00b3\u00a5\u00ed\u00e5\u00d2\u00d7\u00b5\u00d4n1\u00fazYY\u00cb&d9\u2018??S\u00efh\u2013\u00a3\u0003,\u201ac]<br \/>\n<\/code><\/p>\n<p>Notice if already have spaces at the beginning of the script like following diagram:<br \/>\n<a href=\"\/wp-content\/uploads\/2012\/10\/remore-spaces.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"\/wp-content\/uploads\/2012\/10\/remore-spaces.png\" alt=\"Warning: Cannot modify header information - headers already sent by (output started\" title=\"Warning: Cannot modify header information - headers already sent by (output started\" width=\"431\" height=\"136\" class=\"aligncenter size-full wp-image-844\" \/><\/a><br \/>\n<strong>Solution: Remove all spaces at the beginning of the script.<\/strong><br \/>\n<a title=\"Demo PHP force download a file Example\" href=\"http:\/\/demo.webexplorar.com\/PHP\/PHP-force-download-a-file-example\/\" target=\"_blank\" class=\"large button download\" rel=\"noopener noreferrer\">View Demo<\/a><br \/>\n<br \/>\n<span>Download PHP force download a file Example<small> (32 KB)<\/small><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>PHP allows you to change the HTTP Headers of files that you&#8217;re writing, so that you can force a file to be downloaded that normally the browser would load in the same window. Following php script will give to force download a file using php.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[121,1],"tags":[],"class_list":["post-835","post","type-post","status-publish","format-standard","hentry","category-php","category-recent-posts","post--single"],"aioseo_notices":[],"post_mailing_queue_ids":[],"_links":{"self":[{"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/posts\/835","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/comments?post=835"}],"version-history":[{"count":1,"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/posts\/835\/revisions"}],"predecessor-version":[{"id":3759,"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/posts\/835\/revisions\/3759"}],"wp:attachment":[{"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/media?parent=835"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/categories?post=835"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webexplorar.com\/wp-json\/wp\/v2\/tags?post=835"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}