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.
Akash Mehta in PHP |
on Tuesday, April 8th, 2008 at 9:33 pm.
RSS 2.0 |
Leave a response | Trackback