I had mega trouble with a script that was working just fine and decided to quit when we switched to a different domain on the same server. All the file paths are correct, but the script or browser hangs on the "save file" dialog and just says "getting file information" for a few minutes and then the browser errors (not a PHP error message). All I'm doing is sending some file headers and then reading the file 4096 bytes at a time and then sending them to the client until the file pointer reaches EOF. Why did this quit working?


$distribution="/path/to/file.exe";

if ($fd = fopen ($distribution, "r")){

      $size=filesize($distribution);
      $fname = basename ($distribution);

      header("Content-type: application/octet-stream");
      header("Content-Disposition: attachment; filename=\"$fname\"");
      header("Content-length: $size");

      while(!feof($fd)) {
           $buffer = fread($fd, 4096);
           echo $buffer;
      }
      fclose ($fd);
      exit;
}
 

I discovered a very simple work-around, but I would rather use the above code if someone can point out the problem. The workaround for anyone interested is just to redirect directly to the file. The only problem is that anyone with any brains could then find out the original file location. Here's the workaround...

$distribution="/path/to/file.exe";
if ($fd = fopen ($distribution, "r")){
	      header("Location: $distribution");
	      fclose ($fd);
	      exit;
}
 

Simple, but weak...I'd rather use the first version if I can get it working again. Any suggestions?

    replace the while-loop with

    fpassthru($fd);
    • immot

      That would be a good idea if my files were smaller, but my files are 17-50MB in size which means that we can't expect PHP to gracefully read the entire file into the output buffer before sending it to the user. That's why I'm using a loop to read smaller chunks of the data and flush each one to the browser instead of reading the file in one big chunk. This was suggested by the php.net documentation. As I said, it was working perfectly, but when I switched to a new directory on my server, it just quit. I know for a fact that the file is being found and successfully fopened, but either the header() functions aren't working to properly set the content disposition, or there's some other problem. Either way, I'm stuck!

        hi minorgod!

        i've teste your script and i just changed the exit; to exit();!!
        i'm not sure if that is the problem, but if you have some code which should output something after the download it might mess up the file!!

        so, give it a try!!

        <?php
        
        $file = 'download.exe';
        
        if ($fd = fopen ($file, 'r')) {
        	$size = filesize($file);
        	$fname = basename ($file);
        	header("Content-type: application/octet-stream");
        	header("Content-Disposition: attachment; filename=$fname");
        	header("Content-length: $size");
        	while(!feof($fd)) {
        		$buffer = fread($fd, 4096);
        		echo $buffer;
        	}
        	fclose($fd);
        	exit();
        }
        ?>
        

        hope that helps!!

        ceeyaa.MeX

          Write a Reply...