danno74 Posted August 18, 2009 Share Posted August 18, 2009 Greetings all! So I have a download page for some apps at our school. Here is the code: <?php session_start(); $software_title="Impatica"; $date= date("y-m-d"); $time= date("H:i:s"); if (isset($_SESSION['fullname'])) { // record activity in db include("inc/insertrecord.php"); //Location of file, must be out of web root $file_location='impatica.exe'; //open file $file=fopen($file_location,'r'); //get file size $file_size=filesize($file_location); //read the file $content=fread($file,$file_size); //close the file fclose($file); //supply the right file format header('Content-type: application/exe'); header('Expires: 0'); header('Pragma: public'); //force browser to prompt to download file //cool option of this header is that allows you to rename the file header('Content-Disposition: attachment; filename="impatica.exe"'); //finally echo content echo $content; } else header("Location: https://web"); ?> At first I got the error that I was out of memory, so I increased it with this line: ini_set("memory_limit","100M"); That was all fine and good until I started trying to use it with some HUGE self extracting exes (750 MB). I had to up the limit to 1,500M in order for it to work. I watched the load on the server steadily increase whilst it was downloading. Is there anyway around this? I simply want to have the file available without the user knowing the direct link to where it resides. I greatly appreciate any suggestions. Also, I tried this as a suggestion I found on another forum, and for some reason it used the same amount of memory (according the error log anyhow): $total = filesize($filepath); $blocksize = (2 << 20); //2M chunks $sent = 0; $handle = fopen($filepath, "r"); // Push headers that tell what kind of file is coming down the pike header('Content-type: application/exe'); header('Content-Disposition: attachment; filename='.$software_title); header('Content-length: '.$total * 1024); // Now we need to loop through the file and echo out chunks of file data // Dumping the whole file fails at > 30M! while($sent < $total){ echo fread($handle, $blocksize); $sent += $blocksize; Thank you! Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/ Share on other sites More sharing options...
rhodesa Posted August 18, 2009 Share Posted August 18, 2009 don't read it in to a variable...just use readfile() <?php session_start(); $software_title="Impatica"; $date= date("y-m-d"); $time= date("H:i:s"); if (isset($_SESSION['fullname'])) { // record activity in db include("inc/insertrecord.php"); //Location of file, must be out of web root $file_location='impatica.exe'; //supply the right file format header('Content-type: application/exe'); header('Expires: 0'); header('Pragma: public'); //force browser to prompt to download file //cool option of this header is that allows you to rename the file header('Content-Disposition: attachment; filename="impatica.exe"'); //finally echo content readfile($file_location); exit; } else { header("Location: https://web"); } exit; ?> Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901154 Share on other sites More sharing options...
danno74 Posted August 18, 2009 Author Share Posted August 18, 2009 Thanks Aaron! It worked with my two smaller files, no memory adjustments necessary. But I still get an error with the larger one: [Tue Aug 18 15:49:49 2009] [error] [client x] PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 133959681 bytes) in /title2.php on line 28 Do I still need to set the memory with this one? Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901276 Share on other sites More sharing options...
rhodesa Posted August 18, 2009 Share Posted August 18, 2009 hum...how about this: <?php session_start(); $software_title="Impatica"; $date= date("y-m-d"); $time= date("H:i:s"); if (isset($_SESSION['fullname'])) { // record activity in db include("inc/insertrecord.php"); //Location of file, must be out of web root $file_location='impatica.exe'; //supply the right file format header('Content-type: application/exe'); header('Expires: 0'); header('Pragma: public'); //force browser to prompt to download file //cool option of this header is that allows you to rename the file header('Content-Disposition: attachment; filename="impatica.exe"'); //open file $file=fopen($file_location,'r'); while(!feof($file) && $cur<$end) { print fread($file,min(1024*16,$end-$cur)); $cur+=1024*16; } //close the file fclose($file); } else { header("Location: https://web"); } exit; ?> Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901278 Share on other sites More sharing options...
roopurt18 Posted August 18, 2009 Share Posted August 18, 2009 If you have output buffering turned on, then PHP will internally buffer the file before sending it to the client. If that is the case, it doesn't matter how you try and break the file up in your code because PHP will still be holding onto it until you run out of memory. I've seen, but do not have handy, solutions where all output buffering is turned off and in your file read/echo loop you constantly echo and flush so it is all sent immediately. However, there may be a more simple solution if you're on a *nix OS, which may not work but could be worth a shot. Apache should resolve links to the actual resources, so when a file is requested just create a new link to it and redirect the user to the link. Then create a cron job or something else to periodically remove links. Like I said, it may not work at all, but I'd try it if it's appropriate to your environment. Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901389 Share on other sites More sharing options...
danno74 Posted August 19, 2009 Author Share Posted August 19, 2009 Thanks again, Aaron. $cur and $end are not defined, and so the log is sending an error stating this. How would I define those? Roopurt - I am running on Solaris 10, so a solution through apache may be a possibility. Or I can just split the file up. I'm getting to that point, this project is really not that high a priority and taking up too much of my time. I would like to learn more about apache... thanks for sharing your thoughts. Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901799 Share on other sites More sharing options...
MadTechie Posted August 19, 2009 Share Posted August 19, 2009 I guess you could use include include($file_location; Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901803 Share on other sites More sharing options...
rhodesa Posted August 19, 2009 Share Posted August 19, 2009 I guess you could use include include($file_location); ...added closing parenthesis doh...the simple solution is usually the best Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-901851 Share on other sites More sharing options...
danno74 Posted September 8, 2009 Author Share Posted September 8, 2009 So instead of using readfile($file_location); I should use include($file_location); ??? I tried and it failed. Is all the header information still valid? Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-914771 Share on other sites More sharing options...
MadTechie Posted September 8, 2009 Share Posted September 8, 2009 header info should be valid, What doesn't work? Quote Link to comment https://forums.phpfreaks.com/topic/170863-file-too-large-for-fopen/#findComment-914943 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.