469,892 Members | 2,110 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,892 developers. It's quick & easy.

Using PHP to limit download speed

:confused::confused:

I have been on the quest to find a php script that can serve files for downloads and limit the speed at which the file is transfered to the user. I want a faster download speed for registered members and a slower speed for guests.

The only other thing I can think of is using the header() function to force a download for the requested file type and stream the file to the user's browser. Then using sleep() or usleep() on a loop until the download completes.

Anyone have any suggestions or ideas?

~Chipgraphics
Nov 19 '05 #1
12 25544
Niheel
2,443 Expert Mod 2GB
Here is a snippet i found on php.net.

Expand|Select|Wrap|Line Numbers
  1. [font=Courier New]<?php
  2.  
  3. $file = "test.mp3"; [/font][font=Courier New]// file to be send to the client
  4. $speed = 8.5; [/font][font=Courier New]// 8,5 kb/s download rate limit
  5.  
  6. if(file_exists($file) && is_file($file[/font][font=Courier New])) {
  7.  
  8.    header("Cache-control: private"[/font][font=Courier New]);
  9.    header("Content-Type: application/octet-stream"[/font][font=Courier New]); 
  10.    header("Content-Length: ".filesize($file[/font][font=Courier New]));
  11.    header("Content-Disposition: filename=$file" . "%20"[/font][font=Courier New]); 
  12.  
  13.    flush[/font][font=Courier New]();
  14.  
  15.    $fd = fopen($file, "r"[/font][font=Courier New]);
  16.    while(!feof($fd[/font][font=Courier New])) {
  17.          echo fread($fd, round($speed*1024[/font][font=Courier New]));
  18.        flush[/font][font=Courier New]();
  19.        sleep(1[/font][font=Courier New]);
  20.    }
  21.    fclose ($fd[/font][font=Courier New]);
  22.  
  23. }
  24. ?> [/font]
  25.  
Link to page and exact code.
Nov 20 '05 #2
With the constant change of protocols and programming yada yada. I read over what you had suggested and combined a couple of the concepts into one package deal. And it worked on the first try ! :D So, thank you for pointing me in the right direction ! I'll list my source code below.

Here's a function to use PHP to control download bandwith speed:
All original code I borrowed from PHP's online documentation found HERE.

Expand|Select|Wrap|Line Numbers
  1. <?php
  2. function send_file($file, $speed = 100) {
  3.  
  4.     //First, see if the file exists  
  5.     if (!is_file($file)) {
  6.         die("<b>404 File not found!</b>");
  7.     }  
  8.     //Gather relevent info about file
  9.     $filename = basename($file);
  10.     $file_extension = strtolower(substr(strrchr($filename,"."),1));
  11.     // This will set the Content-Type to the appropriate setting for the file
  12.     switch( $file_extension ) {
  13.         case "exe":
  14.             $ctype="application/octet-stream";
  15.             break;
  16.         case "zip":
  17.             $ctype="application/zip";
  18.             break;
  19.         case "mp3":
  20.             $ctype="audio/mpeg";
  21.             break;
  22.         case "mpg":
  23.             $ctype="video/mpeg";
  24.             break;
  25.         case "avi":
  26.             $ctype="video/x-msvideo";
  27.             break;
  28.  
  29.         //  The following are for extensions that shouldn't be downloaded
  30.         // (sensitive stuff, like php files)
  31.         case "php":
  32.         case "htm":
  33.         case "html":
  34.         case "txt":
  35.             die("<b>Cannot be used for ". $file_extension ." files!</b>");
  36.             break;
  37.         default:
  38.             $ctype="application/force-download";
  39.     }
  40.  
  41.     //  Begin writing headers
  42.     header("Cache-Control:");
  43.     header("Cache-Control: public");
  44.     header("Content-Type: $ctype");
  45.  
  46.     $filespaces = str_replace("_", " ", $filename);
  47.     // if your filename contains underscores, replace them with spaces
  48.  
  49.     $header='Content-Disposition: attachment; filename='.$filespaces;
  50.     header($header);
  51.     header("Accept-Ranges: bytes");
  52.  
  53.     $size = filesize($file);  
  54.     //  check if http_range is sent by browser (or download manager)  
  55.     if(isset($_SERVER['HTTP_RANGE'])) {
  56.         // if yes, download missing part     
  57.  
  58.         $seek_range = substr($_SERVER['HTTP_RANGE'] , 6);
  59.         $range = explode( '-', $seek_range);
  60.         if($range[0] > 0) { $seek_start = intval($range[0]); }
  61.         if($range[1] > 0) { $seek_end  =  intval($range[1]); }
  62.  
  63.         header("HTTP/1.1 206 Partial Content");
  64.         header("Content-Length: " . ($seek_end - $seek_start + 1));
  65.         header("Content-Range: bytes $seek_start-$seek_end/$size");
  66.     } else {
  67.         header("Content-Range: bytes 0-$seek_end/$size");
  68.         header("Content-Length: $size");
  69.     }  
  70.     //open the file
  71.     $fp = fopen("$file","rb");
  72.  
  73.     //seek to start of missing part  
  74.     fseek($fp,$seek_start);
  75.  
  76.     //start buffered download
  77.     while(!feof($fp)) {      
  78.         //reset time limit for big files
  79.         set_time_limit(0);      
  80.         print(fread($fp,1024*$speed));
  81.         flush();
  82.         sleep(1);
  83.     }
  84.     fclose($fp);
  85.     exit;
  86. }
  87. ?>
I hope that helps someone out too. Thanks again for pointing me in the right direction !!


~Chipgraphics
Nov 29 '05 #3
Niheel
2,443 Expert Mod 2GB
Hey, congrats on getting the results you were looking for.

Thanks for posting the code for people to learn from, that's what this forum is all about.


~KUB
Nov 29 '05 #4
Flegma
2
I used that script from php.net but i have a problem. When i click on download it starts download, but on ~600kB it stops and dont download....
can abybody explain me thit??
Mar 8 '06 #5
Niheel
2,443 Expert Mod 2GB
Download issues from their server. Maybe wait for a few hrs and try again.
Mar 8 '06 #6
Flegma
2
Download issues from their server. Maybe wait for a few hrs and try again.
it is localhost.....
can it be some option of apache ???
in my webhosting i tried to download 20 MB and it was OK....
Mar 8 '06 #7
pezhvak
17
@Flegma
it's because php stops your script (your script will timeout).. to avoid it, copy following code in the top of your script:

set_time_limit(99999999);
Jul 5 '09 #8
I'm pretty new to PHP. Where in this file would I include the name of the file that I want the user to download or is there a different way to set what file to use this script for? Thanks in advance!
Sep 15 '09 #9
Dormilich
8,652 Expert Mod 8TB
the file name is the functionís first parameter.
Sep 15 '09 #10
My fault. I meant in chipgraphics code.

I would assume I would input the filename somewhere in this line:

Expand|Select|Wrap|Line Numbers
  1. $filename = basename($file);
If not, where?

Thanks in advance.
Sep 15 '09 #11
Dormilich
8,652 Expert Mod 8TB
Expand|Select|Wrap|Line Numbers
  1. function send_file($file, $speed = 100) {
as can be deduced from line 5 to 9.
Sep 15 '09 #12
xphile
1
This code works on my station only if I comment sleep statement! Otherwise browser waiting for file but download doesn't starts. Why?
System: Debian squeeze 2.6.31.6 / Apache 2.2.14-3 / PHP 5.2.1
Dec 16 '09 #13

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

4 posts views Thread by D. Alvarado | last post: by
4 posts views Thread by tjfdownsouth | last post: by
5 posts views Thread by - | last post: by
35 posts views Thread by keerthyragavendran | last post: by
2 posts views Thread by =?Utf-8?B?Z3JlYXRiYXJyaWVyODY=?= | last post: by
1 post views Thread by Waqarahmed | last post: by
reply views Thread by Salome Sato | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.