There are times when you need to store a file (such as one that you sell for profit) outside of the document root of your domain and let the buyers download it via a PHP script so as to hide the real path, web address or URL to that file. Use of this approach enables you to:
- Check for permissions first before rendering the file download thus protecting it from being downloaded by unprivileged visitors.
- Store the file outside of the web document directory of that domain – a good practice in web security in protecting sensitive and important data.
- Count the number of downloads and collect other useful download statistics.
- …
Now the actual tip. Given that you have put the file to be downloaded via the PHP script in place at /home/someuser/products/data.tar.gz, write a PHP file with the following content in it and put it in the web document directory where your site visitors can access:
$path = '/home/someuser/products/data.tar.gz'; // the file made available for download via this PHP file
$mm_type="application/octet-stream"; // modify accordingly to the file type of $path, but in most cases no need to do so
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Type: " . $mm_type);
header("Content-Length: " .(string)(filesize($path)) );
header('Content-Disposition: attachment; filename="'.basename($path).'"');
header("Content-Transfer-Encoding: binary\n");
readfile($path); // outputs the content of the file
exit();
Now your site visitors can and can only download the protected file via the PHP script.
Related Posts
- Simplest PHP Hit Counter or Download Counter – Count the Number of Times of Access (Page Views or File Downloads)
- PHP: Email Attachment Class
- PHP: Why you should use dirname(__FILE__).‘/include.php’ instead of just ‘include.php’
- PHP: File Upload Script (HTML Form + PHP Handler Class)
- PHP: Getting Directory Path and Filename from A Full Path or URL

{ 14 comments… read them below or add one }
First, thanks.
Second, FYI, only relitive paths work on my local apache HTTP server. I can not use ‘/Downloads/test.txt’, I must use ‘../../Downloads/text.txt’. I have yet to get it to work on my real server but I’ll keep trying.
This works like a charm. Thanks very much.
It’s not working for me…
I’ve tried to use it with ‘pdf’ and ‘doc’ files but it doesn’t work.
I even changed the Content-Type to ‘application/pdf’ and ‘application/msword’ but it still doesn’t work.
What it seems to be happening is that it only downloads 1KB of the files.
For the PDF file for example (456KB) when I try to open I get a message saying that the file is damaged.
Any ideas of what may be wrong?
Here’s the script I’m using:
1) get_file.php:
2) index.php:
has a link that calls get_file.php:
Click here to get the file
Thanks!
Make sure there’s no extra unwanted characters in the get_file.php such as hard-to-notice white spaces.
Ok, my bad.
The path was incorrect. The script is working fine now.
Thanks a lot!!!
You are welcome, Rui! :)
Awesome news!
Thanks for sharing this great information. This was helpful to me in learning about how to initiate a file download while protecting the URL of content only to be accessed by authenticated users. Keep up the great work.
Hi your tutorial seems great unfortunatly for me a I have little knoledge of php so I don’t understand how to make it work for me. Can somebody be so kind to explain with some example
sorry and thank you for your time
Stefano
Hi,
I made a php script from your code, but I can still see the download URL on the page, and so can download the files as well. Do I have to call this script from my download page? I have a thank-you page with the download url.
Thanks,
-tejas
The code seems to be working but instead of the file downloading I am getting gibberish in the window. I’ve tried to change the MIME types but nothing seems to be working. The weird thing is that it worked fine the very first time I used it but not since. Does anyone have any ideas?
Thanks.
Hi im new to all this.
I need to automate the process of downloading and installing an exe file abc.exe from say ‘http://10.34.45.21:8080/cruisecontrol/artifacts/xxx_trunk_nightly_build/xxx/test/’
I mean now i have to manually goto ”http://10.34.45.21:8080/cruisecontrol’ then click on each folder before i finally click on the abc.exe file. Then it downloads the exe on my machine. Then i have to double click on the exe to install it. I want to automate this whole process such that when i run the script it will automatically download the exe file and install it. Is it possible to do this using php?
I’m afraid not, or it’d be a major security breach for all the browsers. You can automate the downloading just by giving the full URL address to the file to your site visitors or friends. No need to click through all the directories. However, you can’t make it automatically run on people’s computer after downloading.
I know nothing about PHP, but am looking for a way to allow visitors to part of my site to download an ebook in epub format. Your script is the closest I’ve come to a solution and I thank you for it. However, when the download is completed, the downloaded file receives an additional extension: instead of simply being ROE.epub (the name of the file on the server), it is downloaded as ROE.epub.html.
Any idea what is wrong? (Could it be that the $mm_type has to be set to a different value than “application/octet-stream”?)
{ 1 trackback }