T-Bird Posted May 13, 2009 Share Posted May 13, 2009 I have files that need to be downloaded only if the user has the correct password, thus I'm using the standard readfile() based download method as seen in example 1 of php.net's readfile manual. if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.basename($file)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); ob_clean(); flush(); readfile($file); exit; } The files I'm trying to transfer are on average 80MB zip files stored on the same box that is running the scripts. I have two problems which I think are related... but may not be. a) The user submits the password and it takes approximately a minute for the save dialogue box to appear. PHP logs a timeout error, but the file downloads fine. b) With files less than 60MB I can download several files at a time no sweat. With files over 60MB in size I can only download one file at a time. Anyone who tries to download the file while a transfer is in progress gets an empty placeholder file. I tried switching to a chunked transfer method. I got a code out of the comments on the php.net site that seemed promising and tried it. function readfile_chunked($filename,$retbytes=true) { $chunksize = 1*(1024*1024); // how many bytes per chunk $buffer = ''; $cnt =0; // $handle = fopen($filename, 'rb'); $handle = fopen($filename, 'rb'); if ($handle === false) { return false; } while (!feof($handle)) { $buffer = fread($handle, $chunksize); echo $buffer; ob_flush(); flush(); if ($retbytes) { $cnt += strlen($buffer); } } $status = fclose($handle); if ($retbytes && $status) { return $cnt; // return num. bytes delivered like readfile() does. } return $status; } This solved problem-a as data immediately started to transfer to the browser. I didn't get to test if it solved problem-b because after aprox 25-30 seconds php again (understandably) logged the timeout error and the transfer died. Any clue why php is refusing to allow multiple downloads on code a? Is there a way I can adjust PHP's timeout for only ONE page so that I can use code B without having all my pages use an ugly 1hour timeout? Any other suggestions? Link to comment https://forums.phpfreaks.com/topic/157894-solved-cannot-download-multiple-files/ Share on other sites More sharing options...
MadTechie Posted May 13, 2009 Share Posted May 13, 2009 void set_time_limit ( int $seconds ) seconds The maximum execution time, in seconds. If set to zero, no time limit is imposed. so just add set_time_limit(0); to code B Link to comment https://forums.phpfreaks.com/topic/157894-solved-cannot-download-multiple-files/#findComment-832906 Share on other sites More sharing options...
T-Bird Posted May 13, 2009 Author Share Posted May 13, 2009 Awesome. Worked great. I feel a little dense though. Link to comment https://forums.phpfreaks.com/topic/157894-solved-cannot-download-multiple-files/#findComment-833550 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.