///How to limit file download speed in PHP

How to limit file download speed in PHP

So, your website serves some large files, and you want to control bandwidth use? Or maybe you’re having trouble scaling and can only offer full-speed downloads to paying users. Either way, this script will help you limit file download speed in pure PHP.

<?php
$file = "somefile.zip"; // Filename
$speed = 50; // i.e. 50 kb/s download rate
if(file_exists($file) && is_file($file)) {
   header("Cache-control: private");
   header("Content-Type: application/octet-stream");
   header("Content-Length: ".filesize($file));
   header("Content-Disposition: filename=$file" . "%20");
   flush();
   $fd = fopen($file, "r");
   while(!feof($fd)) {
      echo fread($fd, round($speed*1024)); // $speed kb at a time
      flush();
      sleep(1);
   }
   fclose ($fd);
}

It’s amazing what gems you can find in the PHP manual. I found this one under a comment in the fread function section, and it’s been up there since 2002.

Have a look over that snippet. If you’ve spent a lot of time working with files, it should all make sense. The idea is that the only way to limit download to xx kilobytes per second is to handle the transfer manually, only read xx kilobytes at a time, and then wait a second.

The first few lines are the usual stuff – check file exists, send over some basic headers. Then we start managing the download. We do this through file pointers – if you’ve used fread() to get data from a file before, you know that fread reads a certain number of bytes at a time. You’ve probably just used 1024 bytes at a time, but here we’ll read $speed kilobytes. We then output it, and as PHP/Apache won’t actually send this to the browser just yet (it waits till it has a sizable chunk of data to send), we flush() to force it to. We then wait a second, and repeat till the file is finished.

It’s not perfect, as the wait time would ideally be one second less the time it takes to read xx kilobytes, but it’s pretty close. If you want to limit the download speed to 100kb/s, try setting it to 105kb/s and checking it in a dedicated download manager.

2010-05-25T22:11:09+00:00 April 8th, 2008|PHP|3 Comments

About the Author:

3 Comments

  1. Cyborg June 25, 2008 at 7:34 AM

    Hi,

    How I can use this php script? Shall I put it in the folder where the file i want to control is in ? Do I need to use .htaccess with it ?

    Thanks,

  2. Akash Mehta June 28, 2008 at 4:03 AM

    @Cyborg: place the PHP script anywhere, set the $file variable to point to the file you want to download, then send your users to the PHP script.

  3. Philip December 16, 2009 at 6:12 PM

    I am writing code for file download with speed limitation as was described above. Using sleep in file data sending loop causes browser to hang – it waits for file but download don’t starts. If I comment sleep statement – all works. What could be the problem? System: Debian squeeze 2.6.31.6, Apache 2.2.14-3, PHP 5.2.11

Leave A Comment