Серверная (www.it-simple.ru)

Статистика посещаемости


Врождённая паранойя и стремление к удобству заставили сделать свою статистику посещений сайта.

Объясню. Хост-провайдер такую статистику предоставляет, но, во-первых, раз в сутки, а хочется большей актуальности. Во-вторых, в ней нет некоторых данных, которые хотелось бы увидеть. И в-третьих, хочется свободы, в плане сделать всё удобнее, но рулить чужим веб-сервером мне никто не даст.

Определимся, для чего вообще нужна статистика. Лично мне бывает нужно:

  1. Посмотреть как часто пользователи реально открывают сайт, проходя по внешним ссылкам, по запросам поисковиков и из закладок.
  2. Узнать, какие страницы интересуют посетителей. Составить рейтинг этих страниц.
  3. Посмотреть внешние ссылки, по которым они нашли сайт.
  4. Посмотреть реальное количество постоянных посетителей и случайных пассажиров.

Ещё раз подчёркиваю: по всем параметрам статистику посещений надо настраивать на веб сервере, но рулить чужим веб-сервером нам никто не даст, поэтому будем обходиться тем, что есть.
А есть - PHP и MySQL.

В процессе работы веб-сервер очень тесно сотрудничает с сервером PHP, в том числе передавая ему служебную информацию. Вся эта информация выглядит как набор переменных, объединённых в массив с именем $_SERVER. Для доступа к содержимому отдельной переменной используется конструкция $_SERVER['имя_переменной'].

Идея простая: так как веб-сервер нам недоступен, будем брать нужную информацию из сервера PHP и записывать её в базу MySQL.

Подробное описание массива $_SERVER и список переменных можно посмотреть здесь:
http://www.php.su/articles/?cat=vars&page=015 (http://www.php.su/articles/?cat=vars&page=015)

Какие переменные массива $_SERVER будем использовать

Определимся, что нам нужно для статистики. Что будем сохранять для будущих поколений.

REMOTE_ADDR - айпишник посетителя. Последний реальный айпишник в цепочке маршрута от пользователя.

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

REQUEST_URI - какую страничку запросил пользователь. Прелесть в том, что эта строка содержит не только имя файла на сервере, к которому идёт обращение, но и инструкции для PHP - query_string. URI даётся относительно корня сайта на веб-сервере, то есть если была запрошена страница http://www.it-simple.ru/?p=2849, то в этой переменной будет лежать /?p=2849.

HTTP_REFERER - внешний линк, с которого пришёл посетитель. Если адрес был набран вручную или из закладок, то переменная остаётся пустой.

REQUEST_METHOD - тип запроса на сервер. Полезен, если на сайте есть формы для ввода или комментарии, которые передаются на сервер методом POST. В противном случае всегда (ну, почти всегда, но эти случаи мне неинтересны) равен GET.

Помимо данных из массива $_SERVER нам желательно сохранять также идентификатор записи в базе (ну, это понятно) и дату посещения (она же дата создания записи).

Создаём таблицу в MySQL

Определимся с именами полей и типами данных для хранения нужной информации.

id, идентификатор.
Тип int отлично подойдёт. Занимает 4 байта и способен принимать 232=4294967296 разных значений, что для наших целей больше чем достаточно. Когда станет недостаточно - одной командой сменим его на bigint.

date, текущая дата и время.
Неплохо подойдёт timestamp, в котором дата хранится в виде текстовой строки. Но здесь - на любителя, могут быть варианты.

ip, айпишник клиента.
Без вариантов - четырёхбайтный int.

agent, браузер клиента
ilink, внутренняя ссылка
olink, внешняя ссылка
Для хранения этих данных я выбрал тип text. Не уверен, что это лучшее решение, но пока мне так проще.

method, тип HTTP-запроса.
Интересуют только GET и POST, поэтому наш выбор - enum

Осталось создать нашу таблицу с именем stat и кодировкой utf8, выполнив на сервере MySQL следующий SQL-запрос:

CREATE TABLE `stat` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `date` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  `ip` int(10) unsigned default NULL,
  `agent` text,
  `ilink` text,
  `olink` text,
  `method` enum('GET','POST') default NULL,
  PRIMARY KEY  (`id`),
  KEY `ip` (`ip`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Заполнение статистики

В какой-либо элемент php, который выводится на любой странице сайта надо поместить следующий код:

mysql_query('INSERT INTO stat (ip,agent,ilink,olink,method)
VALUES (INET_ATON("'.$_SERVER['REMOTE_ADDR'].'"),
"'.$_SERVER['HTTP_USER_AGENT'].'",
"'.$_SERVER['REQUEST_URI'].'",
"'.$_SERVER['HTTP_REFERER'].'",
"'.$_SERVER['REQUEST_METHOD'].'")')
or die();

Функция INET_ATON('ip-адрес') преобразует айпишник из классического представления в целое число. Например, INET_ATON('192.168.0.1') вернёт число 3232235521.

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

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

Для просмотра статистики можно написать отдельную страницу на PHP либо использовать запросы к базе. Второй вариант лично мне ближе и удобнее.