Лучший способ реализовать счетчик загрузок? - PullRequest
3 голосов
/ 14 января 2009

Скажем, пользователь нажимает на ссылку, чтобы загрузить файл. Пользователь получает диалоговое окно «Сохранить как», но затем нажимает «Отмена». Как вы это обнаружили? Это означает, что если пользователь нажимает ссылку отмены или не получает весь файл, сервер не должен записывать, что файл был загружен.

Ответы [ 5 ]

3 голосов
/ 14 января 2009

В прошлом я делал это:

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
flush()
log()
exit;

Журнал должен запускаться только после завершения чтения файла, то есть весь файл был передан пользователю. Прошло много времени с тех пор, как я это сделал, и я не знаю, где находится точный код, так что это может быть не точно, но это должно помочь вам.

РЕДАКТИРОВАТЬ Я нашел выше код на php.net, и это более или менее то, что я описывал, этот метод должен работать.

2 голосов
/ 14 января 2009

Я думаю, что некоторые HTTPd не регистрируют файлы в журнале доступа, пока запрос не будет завершен. Вы можете попытаться написать что-то, что анализирует журнал, ищет имя файла и подсчитывает количество строк.

Редактировать: только что попробовал с nginx. Подтвердил мою теорию. Я верю, что то же самое верно и для Apache.

Редактировать # 2: Почему это было модернизировано? Это на самом деле правильный ответ согласно дупе-ссылке на SO. Я стою подтверждённым.

1 голос
/ 14 января 2009

Когда сервер отправляет файл, он не просто мгновенно передает данные по сети, есть пакеты ack, которые должны проходить между клиентом и сервером, отправляющим файл по одному фрагменту за раз.

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

Теперь предоставлено, что пользователь может никогда не получить этот последний блок, но если он запрашивает последний блок (что и делают ack-пакеты), то либо они, либо базовый сетевой протокол приняли, что они получили все блоки, предшествующие этому последнему блоку, и этот может перейти к отправке последнего блока.

Теперь предположим, что

  1. Ваш веб-сервер выполняет нет буферизации.
  2. Это когда ваш веб-сервер блокирует выполнение вашей программы, пока она передает передаваемую вами информацию.

Все, что нужно, - это простая конструкция, подобная этой: (Псевдокод).

1: Open File $foo; 
2: Loop while $foo is not EOF
     3: read  700kilobits from file $foo; 
     4: print 700kilobits of read data to web server
     5: execute webserver 'flush' which blocks until flush is complete. 
     6: <-- Loop
7: If all chunks of 700kilobits were read before user aborted transaction
     8: report file was downloaded. 

Edit Unkwntech ответ практически совпадает с моим.
Его ответ, однако, специфичен для PHP, и я хотел предоставить более общее для языка решение, прежде всего, потому что я разработал отвращение к PHP и не хочу писать для него код, настраивать веб-сервер и тестировать его работу просто чтобы доказать точку зрения, которую я знаю по опыту работ.
Извиняюсь за то, что слишком ленив в этом отношении.

0 голосов
/ 14 января 2009

Одним из способов было бы написать некоторый PHP, который обрабатывает фактическую доставку рассматриваемого файла, предоставляемого в качестве параметра $ _REQUEST. Этот скрипт будет выполнять реальную работу по регистрации загрузки

0 голосов
/ 14 января 2009

Вы говорите о каком-нибудь файле? Если это программа, вы можете сделать так, чтобы она звонила на сервер при установке? Кроме этого, я согласен с Джонатаном, не совсем уверен, что у вас есть к этому доступ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...