Help! Streaming files via PHP get truncated...

Do you have a question? Post it now! No Registration Necessary.  Now with pictures!

Threaded View
Hi there folks

I've got an interesting little problem going on.  On one of my projects,  
I have users log in to retrieve files.   The files themselves are stored  
outside of the www directory on the server, so the only way they can be  
downloaded is for PHP to stream them to the user.

My problem is that my downloads are always "completing" too soon, and  
always around 1.6 -> 1.9 MB.   So, when I try to download a 50MB file,  
I'm told that the download is complete wayyy to early, and of course, the  
file is nothing but garbage.

I have another script on the same server that will zip together a bunch  
of files on the fly and stream it to the browser using a class that i did  
not write personally.  If I tell my system I want to download that 50MB  
file as a .zip file, it works without a problem.  If I tell the system I  
want to download the 50MB file normally (its a PDF) using my  
'stream.php' file, it truncates.  ACK!

some variables that I got from phpInfo(); which may/may not have anything  
to do with this problem (maybe this will help someone/me?):

output_buffering    4096    4096
max_execution_time    210    210
max_input_time    120    120

Anyways, here's the essence of the script I'm using - it's worked on  
other servers (where i've been able to download large files  
successfully).... can anyone offer any suggestions as to why the  
downloads are truncating?  or any other methods of doing what I want to  

thanks.  try to ignore the word-wrap! oh... PHP Version 5.0.4
( Release 1) on a Mac PPC, running apache.



/* downloading a file */

@$vKey = addslashes($_REQUEST['vKey']);

if ($vKey=="") { //no ID?
  popup("We are having trouble locating this specific file.",$vBackPage);

databaseconnect(); //custom function connects to the database

//get the file
$row = singlequery("SELECT f.FilePath,f.FileName FROM Files AS f INNER  
JOIN Folders ON f.FolderID = Folders.FolderID INNER JOIN Projects ON  
Folders.ProjectID = Projects.ProjectID WHERE f.FileKey='$vKey'");

$vFileName = $row["FileName"];
$vFilePath = $row["FilePath"];

if($vFileName=="") {
  popup("The file does not exist, or you do not have access to it.",

//now we stream the file, prompting a download
header("Cache-control: private");  

// We'll be outputting a file
header('Content-Type: application/octet-stream');

// It will be called whatever the file name is called, and given the
// attachment Disposition to force the download

header('Content-Disposition: attachment; filename="'.$vFileName.'"');

// The source... see ya


many thanks,

Re: Help! Streaming files via PHP get truncated...

Quoted text here. Click to load it

hey, guess who JUST read the readfile(); page in the manual?  ;)

Down in the comments section are the following posts...  I've posted them  
here in case anyone is trying to solve this problem in the future and  
stumbled across this thread (hello future!  do you have flying cars?)

( )

flobee at gmail dot com
06-May-2005 02:17
regarding php5:
i found out that there is already a disscussion @php-dev  about readfile
() and fpassthru() where only exactly 2 MB will be delivered. so you may  
use this on php5 to get lager files

... which eventually morphed via 'chrisputnam at gmai<snip>' into the  
following function, which i have used successfully.  thanks chris!

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;
       if ($retbytes) {
           $cnt += strlen($buffer);
       $status = fclose($handle);
   if ($retbytes && $status) {
       return $cnt; // return num. bytes delivered like readfile() does.
   return $status;


Re: Help! Streaming files via PHP get truncated...

Quoted text here. Click to load it

Nicely done ;)

Quoted text here. Click to load it

Site Timeline