By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,312 Members | 1,288 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,312 IT Pros & Developers. It's quick & easy.

Using PHP to limit download speed

P: 8
: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
Share this Question
Share on Google+
12 Replies


Expert Mod 100+
P: 2,330
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

P: 8
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

Expert Mod 100+
P: 2,330
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

P: 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

Expert Mod 100+
P: 2,330
Download issues from their server. Maybe wait for a few hrs and try again.
Mar 8 '06 #6

P: 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

P: 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

P: 2
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
Expert Mod 5K+
P: 8,639
the file name is the functionís first parameter.
Sep 15 '09 #10

P: 2
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
Expert Mod 5K+
P: 8,639
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

P: 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.