А это клавиатура, с помощью которой я творю...
http://kurepin.ru/php/zametki/readfile/
Rambler's Top100
PHP. Заметки. Контроль над раздачей файлов

Рано или поздно в жизни каждого web-программиста появляется задача — контролировать раздачу файлов пользователям.

Наиболее распространенная ситуация — это раздача музыки в формате mp3 и архивов программ.

На сегодняшний день ситуация такова, что владельцам серверов, раздающих какие-либо данные, чаще всего приходится платить за исходящий трафик, поэтому контроль над выкачиваемыми объемами — дело важное и нужное.

Сам по себе подсчет сумм размеров запрошенных файлов не представляет никакой сложности. Для этого достаточно сложить размеры файлов и сделать соответствующие выводы в "кошельке" пользователя услугой. Но как быть, если файл реально не был получен пользователем до конца? К сожалению, такое случается и довольно часто, ибо в на территории бывшего СССР телефонная связь оставляет желать лучшего.

Значит, нам надо решить вполне конкретную задачу: определить, сколько байтов было реально прочтено из файла, получение которого пользователь инициировал.

Не смотря на кажущуюся сложность, задача имеет довольно простое решение. Нам поможет функция PHP readfile().

Функция readfile() делает простейшую операцию — читает данные из файла и направляет их в буфер исходящего потока данных (output buffer). То есть, в нашем случае, просто читает байты из файла и передает их пользователю. Но! После того, как операция успешно завершена или прервана, функция readfile() возвращает количество успешно прочитанных байтов, что, собственно, нам и требуется.

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

Однако, чтобы правильно реализовать контроль над отдачей файла, необходимы некоторые условия работы PHP-скрипта. Дело в следующем.

Порядок выполнения подобного скрипта очевиден:

1. Определяем размер и доступность файла
2. Отправляем нужные http-заголовки (headers)
3. Читаем файл функцией readfile()
4. Получаем объем переданных данных
5. Анализируем результат передачи данных
6. Фиксируем выводы

Проблемы выполнения скрипта могут начаться на стадии выполнения пункта 3. Основных проблем я вижу две:

1. Закончится время, отведенное на работу скрипта, и система принудительно завершит его работу.

2. В процессе передачи разорвется соединение, и скрипт "умрет" сам по себе, не доходя до выполнения пункта 4. То есть мы не зафиксируем объем переданных данных, если файл не был удачно прочитан до конца.

Эти две проблемы решаются двумя директивами интерпретатору, поставленными в начало скрипта:

set_time_limit(0);
ignore_user_abort(1);
Первая директива отменяет лимит времени, отведенного на выполнение скрипта, а вторая сообщает интерпретатору, что следует продолжить выполнение скрипта, не смотря на прерванную связь с пользователем.

Разумеется, в первой директиве можно указать не 0, а максимальное количество секунд, отведенное на работу скрипта.

Главное, чтобы сборка и настройка PHP-движка дозволяла использовать данные директивы.

Собственно, это тот минимум, который необходимо знать для создания своей системы контроля над отдаваемыми файлами. Остальное — дело вашего вкуса и фантазии.

[шаг назад] [печатать] [в начало сайта]



copyright ©2000-2017 Ruslan Kurepin