I want to hide the download folder location so that when the user downloads a file he cannot see the location. I think this can be done using an .htaccess file but how do I do this? Alternatively how can this be done with PHP?
-
No you can't. This is a basic thing to let the user do what he wants with the file he is downloading. – yent Jun 12 '12 at 13:18
-
1I think he means how to hide the URL of the download script – michael Jun 12 '12 at 13:19
-
1@yent actually i just want to hide the location from the user where the file exist – NullPoiиteя Jun 12 '12 at 13:20
-
Oh weah, didn't read it that way ... Using a bit of url rewriting should then help you. – yent Jun 12 '12 at 13:21
3 Answers
This is how I do it in PHP:
<?php
$fakeFileName= "fakeFileName.zip";
$realFileName = "realFileName.zip";
$file = "downloadFolder/".$realFileName;
$fp = fopen($file, 'rb');
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$fakeFileName");
header("Content-Length: " . filesize($file));
fpassthru($fp);
?>
Additionally, if you don't want anyone to have access to the file location, put a file named .htaccess
into your download folder with only the contents:
deny from all
I changed the code a little. First when I say fake file name and real file name, the fake filename is the name that the downloader will download the file as, where the real filename is the name of the actual file in the download folder on your server.
Also, I check to make sure the user is logged in and is able to download the file. If he chooses to download the file, a PHP file is called in a new tab (with the download code from above), then at the end of the file I have the line:
exit;
So when he clicks on the download link, a blank page pops up in a new tab quickly, then quickly exits and the download begins.
EDIT: The download link looks something like this:
<a href="simpleDown.php?id=<?php echo $_GET['id']; ?>" target="_blank">Download!</a>
Where id
is the id
of the download in the database, and in the download script from above I find the entry with that id
, then get its real file name and the fake file name. You can do this without the database though.
Perhaps you would want to look into either Mod Rewrite, or use your PHP script to be able to access the file by simply going to file.php?f=someHash
and then using an octet stream to force the user to download the file.

- 5,075
- 2
- 16
- 26
-
2+1 - This would be the ideal solution. Passing all downloads through a PHP script not only means that you can move the data directory out of the public root but you can also layer security checks on top. Ideally don't reference the files by filename either, use an ID that maps to the file so the name can be changed at will without breaking existing links. – michael Jun 12 '12 at 13:25
What you are going to want to do is have the user directed to fake_url.php
and then rewrite that URL to a different file - real_url.php
. This effectively renders the real_url.php
as hidden because the user is unaware of the redirect happening in your .htaccess
file.
RewriteRule fake_url.php(.*)$ real_url.php?$1 [L,QSA]
In your real_url.php
, you can read the parameters passed through the redirect and then use something similar to readFile()
to send the appropriate file back to the user from within real_url.php
So the user will only see the URL -
https://my-secret-site/download.php?file=file_to_download
And in your real_url.php
you'll know what file was requested by inspecting the $_GET['file']
parameter.
The actual location of the files that the user is downloading does not matter anymore. All downloads go though fake_url.php
and only that script needs to know the real location of the downloads folder.

- 47,311
- 12
- 103
- 131