Without going in to, too much detail about the rest of the site I have a pretty standard user setup with a users table, id, name, password etc. Some users are "free" users and some have paid through paypal this is set by the "user_premium" table as a 1 or 0.
What I want to do is only allow the download of a zip file if the user has premium. Obviously I can hide the link on my pages if they don't, but t开发者_开发知识库hey can still access domain.com/myfile.zip directly.
I tried blocking direct access to the zip via htaccess and used fpassthru in a PHP script to get access to the file e.g. (on the fly example code)
if($user->can_download()) { $fp = fopen('myfile.zip', 'rb'); header("Content-Type: application/zip"); fpassthru($fp); } else { redirect('domain.com/premium.html'); }
However I got memory exhausted errors each time (the file is 4GB).
Is there another way around this?
You should look into using Apache mod_xsendfile
instead of fopen
. With xsendfile
, you respond with an HTTP header with the path to the file on your server, which Apache scoops up and serves the file to the user's browser directly, allowing your PHP script to complete execution.
You can find a great guide for getting started with mod_xsendfile
here: http://codeutopia.net/blog/2009/03/06/sending-files-better-apache-mod_xsendfile-and-php/
From comments in the php doc.
While adding CFLAGS="-D_FILE_OFFSET_BITS=64" immediately before calling "./configure" on the PHP source will enable support for using fopen() on large files (greater than 2 GB), note that -- if such an installation of PHP is used in conjunction with Apache HTTPD [2.x], Apache will become completely unresponsive even when not serving output from a PHP application.
In order to gain large file support for non-web applications while maintaining the operability of Apache, consider making two distinct PHP installations: one with the above CFLAGS specified during configuration (for non-web uses), and the other without this flag (for use with Apache).
精彩评论