PHP Delphi CSS HTML JavaScript Perl API ASP MySQL XML С++ VBasic WEB разработка *NIX CouchDB Hack Python
Главная Статьи PHP Как написать графический счетчик на PHP
Главная
 Главная  Контакты
 
Программинг
Статьи Книги ЧаВО
 
xBOOKi
Fresh Books Операционки Сети
 
Поиск
-------
 
Counters
Яндекс цитирования
Rambler's Top100
-------
 
CryptDisk.4h
Программа которая позволяет создать виртуальный шифрованный логический диск.

cryptdisk.4hack.com

-------
 
 

Как написать графический счетчик на PHP

В этой статье подробным образом описан способ ведения статистики с помощью счетчика выполненного на PHP. Статья рассчитана на низкий/средний уровень подготовленности программиста по PHP.

Программа, описанная в этой статье, позволит вам оснастить ваш вебсайт графическим счетчиком, выполненным в виде баннера 80*31. Счетчик позволяет вести подсчет хитов/хостов за день + хитов за месяц. Основа для хранения данных о посетителях - текстовая база данных. Формат базы следующий:

  1. Основной файл данных - в него пишутся все данные про посещаемость вашего сайта в виде:

    160701127.0.0.1 /test/news.html
    160701127.0.0.1 /me/index.html
    160701127.0.0.2 /me/index.html

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

    "/^([0-9]{6})([^ ]*)[ ]*([^ ]*)$/"

  2. Месячный лог-файл - в этот файл пишутся данные про посещаемость ресурса по дням в следующем виде:

    150701 164
    160701 150
    170701

    Первая группа из 6-ти цифр - это дата, следующая группа цифр - это количество хитов за день. В виде регулярного выражения формат можно записать так:

    "/^([0-9]{2})([0-9]{4})[ ]*([^ ]*)$/"

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

Текст модуля, считающего статистику:

function Count($ip)
{
$str_day=$this->getLastDay(); // Функция "дающая" дату в виде "ддммгг"

# Получаем "рабочую дату" из "месячного" лог файла, а если ее нет (лог-файл пуст или, иначе говоря, первый запуск счетчика - создаем ее)
if ($str_day=="no_day"){$str_day=ShortDay();$this->write_m($str_day);}

# Это для удобства. Все имена лог файлов хранятся в глобальных переменных
$arr=file($GLOBALS['counter_log_daily']);

# Самое главное в нашем счетчике - подсчет статистики
$j=0;
for ($i=0;$i {
if (!preg_match("/^([0-9]{6})([^ ]*)[ ]*([^ ]*)$/",$arr[$i],$var))continue;
if (trim($var[1])==$str_day){$this->hits++;$iparr[$j++]=$var[2];}
}

//Тут идет подсчет хостов за день
$c_iparr = array_count_values ($iparr);
$c_iparr_k = array_keys ($c_iparr);
$this->hosts=count($c_iparr_k);
//$c_iparr_v = array_values($c_iparr);

//Хиты за месяц:
$arr=file($GLOBALS['counter_log_month']);
$hm=0;
for ($i=0;$i {
if (!preg_match("/^([0-9]{2})([0-9]{4})[ ]*([^ ]*)$/",$arr[$i],$var))continue;
if ($var[2]==date("my")){$hm+=$var[3];}

}
$this->month_hits=$hm+$this->hits;

# Так называемое "закрытие дня" - при ситуации когда день текущий не совпадает с днем рабочим записываем в лог-файл количество хитов за рабочий день и переводим рабочий день на текущий.
if ($str_day!=ShortDay())
{
$this->write_m(" ".($this->hits)."\n".ShortDay());
$this->hits=1;
}
}

Наиболее интересным моментом в работе счетчика является защита данных от "порчи" при применении "многопоточных" интернет-серверов. В документации по PHP ясно дается понять, что применять "штатную" функцию flock() для блокирования лог файлов нецелесообразно. Поэтому пришлось выдумать свою, пускай и несколько наивную, схему блокировки. Смысл ее состоит в следующем: для каждого лог-файла, для которого существует возможность одновременной записи и чтения информации, до записи создается id файл . После записи он уничтожается. Если "второй" процесс заметил существование такого файла, то он ждет 1с на его уничтожение.

Подобное реализуется в следующей функции:

function is_month_lock() <--- есть есть id, файл возвращает 1, иначе - 0
function month_lock() <--- Создает ид файл
function month_unlock() <--- Уничтожает id файл

function write_m($str)
{
$i=0;
$write_ok=0;
while ($i<20 && $write_ok==0) <--- Всего 20 циклов ожидания уничтожения файла
{
if (!$this->is_month_lock())
{
$this->month_lock();
$lf=$GLOBALS['counter_log_month'];
$fp = fopen ($lf,"a+");
fwrite($fp,$str);
fflush($fp);
fclose($fp);
$this->month_unlock();
$write_ok=1;
}
else
{
usleep(50000); <--- Один цикл ожидания
$i++;
}
}
if ($write_ok!=1)$this->month_unlock(); <--- Защита от "сбойного" поведения PHP. Для спокойствия (на медленных серверах) можете увеличить количество периодов до 100 шт.
return $write_ok;
}

В конце приведу текст модуля, выводящего на экран рисунок со счетчиком. В особенных пояснениях текст, я думаю, не нуждается. Однако если вопросы возникнут - читайте статьи на сайте "Программы для бизнеса", посвященные работе с графикой в PHP (см. ниже "Ссылки по теме").

function MakePNG ($imgname,$_hi,$_ho,$_ha)
{
$m=$GLOBALS['counter_max_digits'];
$hi=AddSpaces($_hi."",$m,"l");
$ho=AddSpaces($_ho."",$m,"l");
$ha=AddSpaces($_ha."",$m,"l");
$im = @ImageCreateFromPNG ($imgname); /* Attempt to open */
$tc = ImageColorAllocate ($im, 0, 0, 60);

if (!$im)
{
$im = ImageCreate (80, 31); /* Create a blank image */
$bgc = ImageColorAllocate ($im, 255, 255, 255);
ImageFilledRectangle ($im, 0, 0, 150, 30, $bgc);
}
$l=81-6*$m;
ImageString ($im, 2, $l, -1, $hi,$tc);
ImageString ($im, 2, $l, 19, $ho ,$tc);
ImageString ($im, 2, $l, 9, $ha ,$tc);
return $im;
}

function OutPut()
{
$im = $this->MakePNG("png.png",$this->month_hits,$this->hosts+0,$this->hits+0);
ImagePng ($im);
ImageDestroy ($im);
}

Полный исходный текст программы вы можете взять на сайте "Программы для бизнеса" в разделе "Загрузка". Перейти >>>

Ccылки по теме:

  1. Исходный текст статьи на сайте "Программы для бизнеса." Перейти >>>
  2. Статья "Начинаем работу с рисунками в php для Windows." Перейти >>>
  3. FAQ PHP на сайте "Программы для бизнеса." Перейти >>>

 

Кириллов Арсен г.Львов 2001 г. softm@ukr.net



Свежее
Резервное копирование rsync-ом
DNS Amplification (DNS усиление)
Алгоритм Шинглов — поиск нечетких дубликатов текста
Metasploit Framework. Обзор
Использование CouchDB
-------



 
Copyright © 2003-2009   Frikazoid.
Rambler's Top100