Gideon-IT Posted November 10, 2011 Share Posted November 10, 2011 I'm a newbie to PHP but I want to amend a website I run for a musician friend of mine so that when people purchase his albums (sold as ZIP files) they don't see the link to the actual file, but PHP generates a randomly named copy, then downloads it for them and then deletes the copy when complete. All works well except the download. With the large files the download goes to about 1/2 way through and then just stalls until it aborts. Here's the code... <?php $path = "../_downloads/"; // change the path to fit your websites document structure $fullPath = $path.$_GET['file']; if ($fd = fopen ($fullPath, "r")) { $fsize = filesize($fullPath); $path_parts = pathinfo($fullPath); $ext = strtolower($path_parts["extension"]); switch ($ext) { case "zip": header("Content-type: application/zip"); // add here more headers for diff. extensions header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download break; default; header("Content-type: application/octet-stream"); header("Content-Disposition: filename=\"".$path_parts["basename"]."\""); } header("Content-length: $fsize"); header("Cache-control: private"); //use this to open files directly stream_set_timeout($fd, 600); while(!feof($fd)) { $buffer = fgets($fd,8192); echo $buffer; } } $info = stream_get_meta_data($fd); fclose ($fd); if ($info['timed_out']) { echo 'Connection timed out!'; } else { echo 'Done'; } exit; // example: place this kind of link into the document where the file download is offered: // <a href="download.php?file=some_file.pdf">Download here</a> ?> The link to run it is below... www.godfreyb.com/_scripts/download.php?file=cd12_vg.zip I've tried the @readfile(); function and this does the same thing, get to about 60.5 Mb and stalls. I even tried passthru('cat ' . $fullPath); to send the file and that doesn't send anything at all. The site is hosted by FastHosts on a Windows 2008 server with PHP5 installed. Directly linking to the ZIP file results in a perfect download everytime. Can anyone suggest a way to get this working? It's driving me nuts! Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/ Share on other sites More sharing options...
Adam Posted November 10, 2011 Share Posted November 10, 2011 How long does it take for execution to stop? You're increasing the time out of the stream, but not the PHP execution itself. You'll possibly need to just increase the max execution time. Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/#findComment-1287055 Share on other sites More sharing options...
Gideon-IT Posted November 10, 2011 Author Share Posted November 10, 2011 How do I do that? It's worth a try! Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/#findComment-1287059 Share on other sites More sharing options...
Gideon-IT Posted November 10, 2011 Author Share Posted November 10, 2011 To avoid being a lazy arse I looked it up on Google! I've added the following lines to the beginning of the script... ini_set('max_execution_time', 1200); ini_set('memory_limit','1024M'); And am re-testing. Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/#findComment-1287061 Share on other sites More sharing options...
Adam Posted November 10, 2011 Share Posted November 10, 2011 Yup, or using set_time_limit. Forgot to add, because you're on a Windows server this is the case. On Linux the max execution time doesn't include stream operations, which you had increased the time-out of. I suspect you wouldn't be getting this problem on Linux. Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/#findComment-1287064 Share on other sites More sharing options...
Gideon-IT Posted November 10, 2011 Author Share Posted November 10, 2011 Adam, Well thanks to your excellent suggestions we've moved forward somewhat. Now I get 132Mb of my 156Mb download - but still not all of it! The modified code is below. Any other ideas? <?php ini_set('max_execution_time', 1200); ini_set('memory_limit','256M'); set_time_limit(1200); $path = "../_downloads/"; // change the path to fit your websites document structure $fullPath = $path.$_GET['file']; if ($fd = fopen ($fullPath, "r")) { $fsize = filesize($fullPath); $path_parts = pathinfo($fullPath); $ext = strtolower($path_parts["extension"]); switch ($ext) { case "zip": header("Content-type: application/zip"); // add here more headers for diff. extensions header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // use 'attachment' to force a download break; default; header("Content-type: application/octet-stream"); header("Content-Disposition: filename=\"".$path_parts["basename"]."\""); } header("Content-length: $fsize"); header("Cache-control: private"); //use this to open files directly stream_set_timeout($fd, 1200); ob_clean(); flush(); while(!feof($fd)) { $buffer = fgets($fd,1024); echo $buffer; } } $info = stream_get_meta_data($fd); fclose ($fd); if ($info['timed_out']) { echo 'Connection timed out!'; } else { echo 'Done'; } exit; // example: place this kind of link into the document where the file download is offered: // <a href="download.php?file=some_file.pdf">Download here</a> ?> Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/#findComment-1287068 Share on other sites More sharing options...
Gideon-IT Posted November 10, 2011 Author Share Posted November 10, 2011 For full PHP info see here... http://godfreyb.com/_scripts/test.php Quote Link to comment https://forums.phpfreaks.com/topic/250866-problems-downloading-files-over-about-30mb-via-php/#findComment-1287110 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.