Trying to implement a download script with fread function

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
rocco
Forum Newbie
Posts: 4
Joined: Sun Jun 15, 2008 12:12 pm

Trying to implement a download script with fread function

Post 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
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Trying to implement a download script with fread function

Post 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.
rocco
Forum Newbie
Posts: 4
Joined: Sun Jun 15, 2008 12:12 pm

Re: Trying to implement a download script with fread function

Post 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.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Trying to implement a download script with fread function

Post by Ollie Saunders »

Try removing the call to round() passing $speed*1024 to fread() directly.
rocco
Forum Newbie
Posts: 4
Joined: Sun Jun 15, 2008 12:12 pm

Re: Trying to implement a download script with fread function

Post by rocco »

changed to: echo fread($fdl, $speed*1024);
but still the same is happening.
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Trying to implement a download script with fread function

Post 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.
rocco
Forum Newbie
Posts: 4
Joined: Sun Jun 15, 2008 12:12 pm

Re: Trying to implement a download script with fread function

Post 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;
}
 
User avatar
Ollie Saunders
DevNet Master
Posts: 3179
Joined: Tue May 24, 2005 6:01 pm
Location: UK

Re: Trying to implement a download script with fread function

Post by Ollie Saunders »

Oh right yeah, two fopen()s probably doesn't help. Glad you got it sorted.
Post Reply