067 607 57 84
МЕНЮ

PHP - як обмежити швидкість завантаження файлу

Створення сайтів Львів

Іноді потрібно обмежити швидкість завантаження файлу. Добре - якщо є можливість налаштувати це на веб-сервері - тоді все просто і ресурсів сервер буде споживати менше. Але, що робити якщо доступу до налаштувань веб-сервера немає? Правильно - треба писати свою милицю. І php нам допоможе в цьому.

Є сайт, який надає файли для завантаження. І ми хочемо зробити обмеження швидкості завантаження тільки для незареєстрованих користувачів, а для зареєстрованих користувачів немає ніяких обмежень. Причина для обмеження швидкості скачування може бути і іншою: користувач, який оплатив скачування без обмежень - отримує файл на максимальній швидкості, а той, хто поскупився - буде завантажувати дуже повільно.

<?php
// швидкість скачування - 128КБ в сек.
$speed = 1024*128;
// ім’я файла
$filename = 'music.mp3';
// розмір файла
$filesize = filesize($filename);
// зміщення від початку файлу
$range = 0;
 
while( is_already_download() ) {
  // спимо поки у користувача є активні потоки
  sleep(1);
}
 
// відкриваємо файл для читання
$f = fopen($filename, 'rb');
 
if (isset($_SERVER['HTTP_RANGE'])) { // чи підтримується докачка
  $range = $_SERVER['HTTP_RANGE'];
  $range = str_replace('bytes=', '', $range);
  $range = str_replace('-', '', $range);
  if ($range) fseek($f, $range);
}
 
// якщо є зміщення
if ($range) {
  header($_SERVER['SERVER_PROTOCOL'].' 206 Partial Content');
} else {
  header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
}
 
header( 'Last-Modified: '.date('D, d M Y H:i:s T', filemtime($filename)) );
header('Content-Length: '.($filesize-$range));
header('Accept-Ranges: bytes');
header('Content-Range: bytes '.$range.'-'.($filesize - 1).'/'.$filesize);
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="'.$filename.'"');
 
while( !feof($f) ) {
  echo fread($f, $speed);
  flush();
  sleep(1); // засинаємо
}
 
// закриваєм файл
fclose($f);
 
// видаляємо інформацію про з’єднання з БД
mysql_query("DELETE FROM `sessions` WHERE `session_ip`='".$_SERVER['REMOTE_ADDR']."' LIMIT 1");
 
function is_already_download() {
  // перевіряємо на наявність з’єднання від користувача
  $res = mysql_query("SELECT `session_ip` FROM `sessions` WHERE `session_ip`='".$_SERVER['REMOTE_ADDR']."' LIMIT 1");
  if (mysql_num_rows($res)) {
    return true;
  } else { // якщо запис відсутній, то додаєм
    mysql_query ("INSERT INTO `sessions` VALUES ('".$_SERVER['REMOTE_ADDR']."')");
    return false;
  }
}
?>
                    

В даному випадку ми використовуємо таблицю MySQL sessions, в якій всього одне поле - IP-адреса скачуваного. При наявності IP-адреси скачуваного в таблиці встановлюємо true, в іншому випадку записуємо його і встановлюємо false.