I have .mp3 files in my website and I want to set my site so that after my users have logged in they can download files. If users are not logged in they won't be able to download files. I do not want anyone to be able to find the path of the files.
-
possible duplicate of [Restrict file access to authorized php users](http://stackoverflow.com/questions/738500/restrict-file-access-to-authorized-php-users) – deceze Apr 28 '11 at 03:43
-
Only when you are logged in , or allow downloads for people who have looged in ( not you ) ? – tereško Apr 28 '11 at 03:48
4 Answers
I'd make the file impossible to access via an HTTP request alone, and with PHP, just print it out:
<?php
session_start();
if (isset($_SESSION['logged_in'])) {
$file = '/this/is/the/path/file.mp3';
header('Content-type: audio/mpeg');
header('Content-length: ' . filesize($file));
readfile($file);
}
?>

- 289,723
- 53
- 439
- 496
-
Not a fan of PHP in general. I'm just doing this with my basic knowledge of PHP, but thanks for the function. PHP has many ;) – Blender Apr 28 '11 at 03:51
-
1
-
3`serve_file_if_user_logged_in('foo.mp3');` I'm submitting it to PHP6 ;) – Blender Apr 28 '11 at 03:54
You can create a token based on something like the user session id and some random value. Then, the logged in user urls would be like :
/download.php?token=4782ab847313bcd

- 46,820
- 25
- 86
- 129
- Place the MP3 files above your docroot, or if that is impossible, deny access to them with
.htaccess
(if using Apache). - Verify a user is logged in.
- Send the appropriate headers and
readfile()
on the MP3 when the user requests the file.

- 479,566
- 201
- 878
- 984
-
Wouldn't it be easier to keep mp3 outside the DOCUMENT_ROOT ? Then there is no need to use .htaccess , is it ? – tereško Apr 28 '11 at 03:46
-
4
-
kinda depends on your definition of "above" , especially since / is a "root". – tereško Apr 28 '11 at 04:22
-
2
From wordpress.stackexchange.com/a/285018
Caution: Be wary of using this PHP-driven file download technique on larger files (e.g., over 20MB in size). Why? Two reasons:
PHP has an internal memory limit. If
readfile()
exceeds that limit when reading the file into memory and serving it out to a visitor, your script will fail.In addition, PHP scripts also have a time limit. If a visitor on a very slow connection takes a long time to download a larger file, the script will timeout and the user will experience a failed download attempt, or receive a partial/corrupted file.
Caution: Also be aware that PHP-driven file downloads using the readfile()
technique do not support resumable byte ranges. So pausing the download, or the download being interrupted in some way, doesn't leave the user with an option to resume. They will need to start the download all over again. It is possible to support Range requests (resume) in PHP, but that is tedious.
In the long-term, my suggestion is that you start looking at a much more effective way of serving protected files, referred to as X-Sendfile in Apache, and X-Accel-Redirect in Nginx.
X-Sendfile and X-Accel-Redirect both work on the same underlying concept. Instead of asking a scripting language like PHP to pull a file into memory, simply tell the web server to do an internal redirect and serve the contents of an otherwise protected file. In short, you can do away with much of the above, and reduce the solution down to just header('X-Accel-Redirect: ...')
.

- 6,364
- 11
- 69
- 117