Page 1 of 1

Trying to implement a download script with fread function

Posted: Sun Jun 15, 2008 12:28 pm
by rocco
Hello,
I'm trying to implement a download script with fread function.
This is the original download script, without fread function:

Code: Select all

 
function send_file($path, $file){
   
   # Make sure the file exists before sending headers
   #-------------------------------------------------
   $mainpath = "$path/$file";
   $filesize2 = sprintf("%u", filesize($mainpath));
 
   if(!$fdl=@fopen($mainpath,'r')){
      #include ("$header");
      print "<p>ERROR - Invalid Request (Downloadable file Missing or Unreadable)</p><br /><br />";
      die;
   }else{
      set_time_limit(0);
      # Send the headers then send the file
      #------------------------------------
      header("Cache-Control: ");# leave blank to avoid IE errors
      header("Pragma: ");# leave blank to avoid IE errors
      header("Content-type: application/octet-stream");
      header("Content-Disposition: attachment; filename=\"".$file."\"");
      header("Content-length:".(string)($filesize2));
      #header("Content-Length: ".$filesize2);
      #header("Content-Length: $filesize2");
      sleep(1);
      fpassthru($fdl);
   }
   return;
}
 

And this is with the fread function I've tried to implement:

Code: Select all

 
function send_file($path, $file){
   
   # Make sure the file exists before sending headers
   #-------------------------------------------------
   $mainpath = "$path/$file";
   $filesize2 = sprintf("%u", filesize($mainpath));
   $speed = 50; // i.e. 50 kb/s download rate
   if(!$fdl=@fopen($mainpath,'r')){
      #include ("$header");
      print "<p>ERROR - Invalid Request (Downloadable file Missing or Unreadable)</p><br /><br />";
      die;
   }else{
      set_time_limit(0);
      # Send the headers then send the file
      #------------------------------------
      header("Cache-Control: ");# leave blank to avoid IE errors
      header("Pragma: ");# leave blank to avoid IE errors
      header("Content-type: application/octet-stream");
      header("Content-Disposition: attachment; filename=\"".$file."\"");
      header("Content-length:".(string)($filesize2));
      #header("Content-Length: ".$filesize2);
      #header("Content-Length: $filesize2");
      flush();
 
      $fdl = fopen($file, "r");
      while(!feof($fdl)) {
      echo fread($fdl, round($speed*1024)); // $speed kb at a time
      flush();
      sleep(1);
   }
      fpassthru($fdl);
   }
   return;
}
 
But it doesn't work. The download reach a max 0.5kbps and it never ends. The files that have to be downloaded are MP3 of 80/90 MB each.
I'm new here and I'm trying to learn some php, so if you can make me understand what I'm doing wrong I will really appreciate it.
Thanks so much!
rocco

Re: Trying to implement a download script with fread function

Posted: Mon Jun 16, 2008 3:38 am
by Ollie Saunders
You should open the file with "rb" instead of just "r" because the files are binary. Does that make any difference? Also remove the call to fpassthru() at the end.

Re: Trying to implement a download script with fread function

Posted: Mon Jun 16, 2008 12:50 pm
by rocco
Thanks Ole for your reply,

I've tried opening the file with "rb" instead of just "r" but nothing change and anyway on the original code, which is properly working without fread function, the file is opened with just "r".

I've tried to remove the call to fpassthru() at the end, but it doesn't work.
I've also tried to add "@fclose($fdl);" at the end without fpassthru() or even after fpassthru() being included, but nothing. Always the same problem: the download reaches a max 0.5kbps and it never ends.

Re: Trying to implement a download script with fread function

Posted: Mon Jun 16, 2008 1:43 pm
by Ollie Saunders
Try removing the call to round() passing $speed*1024 to fread() directly.

Re: Trying to implement a download script with fread function

Posted: Mon Jun 16, 2008 2:15 pm
by rocco
changed to: echo fread($fdl, $speed*1024);
but still the same is happening.

Re: Trying to implement a download script with fread function

Posted: Mon Jun 16, 2008 4:06 pm
by Ollie Saunders
Does it work if you remove the sleep() call?
What about removing the flush() call as well?
Why are you passing the filesize thing through sprintf? Try putting filesize($mainpath) directly into the header.
Try a different browser.

Maybe try change the content-disposition to inline and then use firebug (or any other tool of your choosing) to examine the response headers and see if they are as you expect.

Re: Trying to implement a download script with fread function

Posted: Mon Jun 16, 2008 8:13 pm
by rocco
done it! now it's working like a charm. tested in FF 2.0.0.14 and IE6

here's the fixes:

removed: $fdl = fopen... at line 26 of the above mod vers.
removed: fpassthru ($fdl); at line 32 (as Ole told me to do)
added: fclose ($fdl) before "return;" at the end
and checked that all braces were properly closed.

Here's the fixed and working code, in case somebody need it. Thanks so much Ole for your kind help n suggestions!

Code: Select all

 
function send_file($path, $file){
   
   # Make sure the file exists before sending headers
   #-------------------------------------------------
   $mainpath = "$path/$file";
   $filesize2 = sprintf("%u", filesize($mainpath));
$speed = 90; // i.e. 50 kb/s download rate
   if(!$fdl=@fopen($mainpath,'r')) {
      #include ("$header");
      print "<p>ERROR - Invalid Request (Downloadable file Missing or Unreadable)</p><br /><br />";
      die;
   }else{
      set_time_limit(0);
      # Send the headers then send the file
      #------------------------------------
      header("Cache-Control: ");# leave blank to avoid IE errors
      header("Pragma: ");# leave blank to avoid IE errors
      header("Content-type: application/octet-stream");
      header("Content-Disposition: attachment; filename=\"".$file."\"");
      header("Content-length:".(string)($filesize2));
      #header("Content-Length: ".$filesize2);
      #header("Content-Length: $filesize2");
   flush();
   while(!feof($fdl)) {
      echo fread($fdl, round($speed*1024)); // $speed kb at a time
   flush();
      sleep(1);
   }
   fclose ($fdl);
   }
   return;
}
 

Re: Trying to implement a download script with fread function

Posted: Tue Jun 17, 2008 12:08 am
by Ollie Saunders
Oh right yeah, two fopen()s probably doesn't help. Glad you got it sorted.