Отправляет email-рассылки с помощью сервиса Sendsay

PHP понемножку

  Все выпуски  

PHP понемножку. Ограничение числа подключений при закачке файлов в PHP.


Развивая тему закачки файлов через скрипты PHP с ограничением скорости рассмотрим ограничение количества скачиваемых файлов.

Для ограничения количества закачиваемых файлов, по какому-либо критерию, нам потребуется организовать обмен данными между двумя копиями одного скрипта, запущенными в пределах сеанса клиента. Это можно организовать через сохранение информации о запуске скрипта в базе данных или файле, установкой «куки» или использованием сессионных переменных. Правда, ограничения привязанные к сессии или cookie вряд ли могут надёжно помочь нам в этом случае. Клиенту достаточно очистить cookies или воспользоваться другим браузером или программой закачки. Единственный реальный на мой взгляд способ должен использовать ограничение количества закачиваемых файлов на основе IP-адреса клиента.

Продумаем функционал скрипта для описанной задачи. При запуске он должен выяснить IP-адрес клиента и получить число файлов уже скачиваемых с него. Если это число 0 или не превышает установленного ограничения, то скрипт должен увеличить его на единицу и начать отдачу файла, в противном случае отказать в доступе к файлу. По завершении работы скрипт должен уменьшить число скачиваемых файлов на единицу. Последнее условие очень важно, поскольку этот код должен выполняться даже при разрыве соединения самим клиентом, хотя в этом случае код может быть выполнен не полностью. Для того того чтобы обеспечить его выполнение придется использовать функцию register_shutdown_function(). Поскольку вопросы разных способов отдачи файла мы уже подробно рассмотрели ранее в готовых функциях, нас будет интересовать только их обвязка, ограничивающая число подключений с одного IP-адреса.

Итак, пусть наш скрипт закачки находится в файле file.php, а имя файла из того же каталога или из его подкаталога задается в запросе через параметр file. Код скрипта будет таким:

// Регистрируем функцию завершения скрипта. Функция должна увеличить на единицу значение    
// счетчика закачек для данного IP. Конкретная реализация этой функции может быть любой.  
// При обрыве соединения сервер сразу прекращает работу скрипта, поэтому увеличенное на    
// единицу значение счетчика закачек не будет уменьшено назад. Только через регистрацию    
// функции на завершение можно гарантировать ее вызов не только при нормальном завершении  
// работы, но и при обрыве соединения с клиентской или серверной стороны.                                
register_shutdown_function ("thread_stop");
// Стартуем данный поток. Эта функция должна увеличить на единицу значения счетчика числа  
// закачек с данного IP. Конкретная реализация этой функции может быть любой.
thread_start();
// Задаём количество потоков на одну сессию. Если  задано 0, то потоки не ограничиваются
$thread_limit = 3;
// Функция thread_number() возвращает нам номер текущего потока. Конкретная реализация этой  
// функции может быть любой.
if ($thread_limit > 0 && thread_number() > $thread_limit) {
// Если задано ограничение числа потоков и полученный номер текущего потока превышает лимит,
// то отдаём клиенту заголовок 503 (Сервис временно недоступен) примерное время ожидания    
// (240 секунд)и прерываем его выполнение. Можно вместо этого при помощи функции header()    
// перенаправить его на специальную страницу, где будет описана причина ограничений:        
// превышение числа одновременно закачиваемых файлов с одного IP-адреса.                                                                      
  header($_SERVER["SERVER_PROTOCOL"] . " 503 Service Temporarily Unavailable");
  header("Status: 503 Service Temporarily Unavailable");
  header("Retry-After: 240");
  header("Connection: Close");
  exit();
}
else {
// Отдаем клиенту файл при помощи любой из функций, описанных в предыдущих заметках. Имя    
// файла для закачки передается через переменную file.
  file_download($_GET['file']);
}

Функция file_download() может применяться любая из моих предыдущих заметок. Либо просто передающая файл на закачку напрямую или через скрипт, либо ограничивающая скорость закачки.

 

Ну а как реализованы функции thread_start(), thread_stop() и thread_number() мы рассмотрим в следующей заметке. Это будут два варианта: сохранение числа закачек в БД и в файловой системе. Хотя стоит отметить, что в PHP 5 имеются и другие способы обмена данными между скриптами.


В избранное