пятница, 25 сентября 2009 г.

Количество скачиваний файла на PHP

На одном из форумов мне задали вопрос: «Как реализовать подсчет количества скачиваний файла?». Покумекав немного я решил написать пример подобной реализации с использованием не баз данных, но файлов. И так приступим. Прежде всего надо разбить задачу на более простые подзадачи.
1) Как подсчитывать;
2) Как хранить подсчитанные данные;
3) Как их выдергивать и преподносить пользователю.
Это-наш план реализации. Давайте теперь разбираться по пунктам, что и как надо сделать. Прежде всего подсчет. Понятно что напрямую файл отдавать нельзя прежде чем его отдать надо прибавить к счетчику +1. Значит это реализуем примерно вот так:


<?php

//код файла req.php

define('URL_DIR','http://phpbegun.ru/files_dir/');

define('ABS_DIR',$_SERVER['DOCUMENT_ROOT']);

//Определяем нужные нам константы

$namefile htmlspecialchars(str_replace("/","",$_GET['name'])); 

//Через гет передаем параметр-имя

if(!$namefile

{

    echo 
'Произошла ошибка! Файл с таким именем не найден.';

}

$array = array(); //массив данных

if(file_exists(ABS_DIR.'/schet.txt'))

{

    
$array unserialize(file_get_contents(ABS_DIR.'/schet.txt'));

    
//Файл который будет содержать данные о кол-ве скачиваний

    //в виде сериализованного массива

    
if(!$array[$namefile]) $array[$namefile] = 0;

    
$schet $array[$namefile]+1;

    
//$array[$namefile] содержит кол-во скачиванй этого файла

}

else 

{

    
$schet 1;

}

$array[$namefile] = $schet;

//присваиваем новое значение элементу массива

$array serialize($array);

//сериализуем данные

@file_put_contents(ABS_DIR.'/schet.txt',$array);

//пишем в файл причем не проверяем 

//записалось или нет ибо скачивание 

//должно начаться независимо от этого 

header("Location: ".URL_DIR."$namefile");

//Переадресуем запрос на скачиваемый файл

?>

Итак первая часть кода есть. Данный скрипт должен выполняться перед началом скачивания файла, т.е. на него должны вести все ссылки с вашего сайта для скачивания. Этот сценарий подразумевает что права на корневой дирректории и на самом файле будут таковы чтобы была возможна запись (cmod 0777). Так же хочу заметить, что для больших файлохранилищ даный алгоритм не лучшее решение и гораздо правильнее было бы использовать MySQL. Но для тех у кого небольшой сайт с малым количеством файлов это наиболее оптимальный вариант. Фактически мы решили задачи 1 и 2. Храним данныее в файле в сериализованном виде (настоятельно рекомендую почитать о функциях serialize и unserialize в официальном мануале, очень полезная штука). Кроме того сначала подсчитываем количество скачиваний, увеличиваем его, сохраняем в файл и потом выводим. как же теперь преподносить данные пользователю? При формировании страницы надо лишь считывать массив данных, и выдергивать с именем данного файла нужное нам число. Примерно вот так:


<?php

define
('URL_DIR','http://phpbegun.ru/files_dir/');

define('ABS_DIR',$_SERVER['DOCUMENT_ROOT']);

$data unserialize(file_get_contents(ABS_DIR.'/schet.txt'));

echo 
'Вот тут можно скачать файл '.

'<a href="/files_dir/req.php?name=name.txt">Names(',$data['name.txt'],')</a>';

?>

Простейший счетчик скачиваний файлов готов. Советую вам все define вынести в отдельный файл, чтобы не определять их и в файле скачивания и в файле вывода, и подключать через require_once. На этом пожалуй закончу данную статью, ибо пищу для размышлений я вам дал, а что-то более интересное и элегантное вы сможете конечно же написать и сами если постараетесь. Надеюсь, что вы поделитесь своими вариантами решений, будет интересно посмотреть.
Удачи в обучении :)

1 комментарий:

  1. Да а как же сделать так чтобы точно быть уверенным что файл скачали ? Так ведь можно просто нажать, и прибавиться 1

    ОтветитьУдалить