При работе над одним из «опекаемых» сайтов возник��а необходимость построить некое подобие системы внутренней статистики посещения страниц сайта. На помощь пришел Google Analytics, точнее Google Analytics API.


Собственно, задача стояла следующая:
  • имеется арендованный выделенный сервер с небольшим запасом ресурсов, самописная (перешедшая по наследству) CMS, реализованная с помощью PHP и MySQL, «не сильно» оптимизированная под высокие нагрузки
  • необходимо построить соответствие id документа => кол-во уникальных просмотров документа за сутки
  • хранить статистику также за неделю, месяц, год


Сразу следует оговориться, что достаточно долгое время использовался «встроенный» механизм подсчета и хранения этой статистики, который периодически переписывался, оптимизировался, дописывался, переносился и проч…

Итогом стало принятие решения об использовании в качестве хранилища статистики стороннего сервиса (итоговый вариант стал некоторым гибридом с буферной таблицей в базе). После недолгих раздумий было решено использовать Analytics через API.

Дабы не изобретать велосипед, решил использовать вот эту библиотеку для доступа к данным Analytics.

Далее, пусть URL всех страниц, для которых нужна статистика унифицированы — www.site.ru/%id%.html, где id — строго целочисленный параметр. При необходимости заменой одного регекспа это требование легко обходится.

Для примера, пусть все материалы, для которых нужна статистика лежат в одной таблице art (id, name,… ) в базе и id этой таблицы совпадает с id в URL.

Далее, создаем буферную таблицу для хранения статистики у себя:
CREATE TABLE `art_stat` (
  `art_id` INT NOT NULL ,
  `day_stat` INT DEFAULT '0',
  `week_stat` INT DEFAULT '0',
  `month_stat` INT DEFAULT '0',
  `year_stat` INT DEFAULT '0',
  UNIQUE (
   `art_id`
  )
);


* This source code was highlighted with Source Code Highlighter.


Далее, привожу сам код с минимальными комментариями.
<?php

set_time_limit(0);

require_once 'start.php'; // Подключение к базе и прочее

require_once 'gapi.class.php'; // Подключаем класс

// Данные для входа в аккаунт - подставляем свои значения
define('ga_email','...');
define('ga_password','...');
define('ga_profile_id','...');

// Запускаем обновление статистики
// Метка означает период, за который мы берем статистику
// d - за сутки
// w - за неделю
// m - за месяц
// y - за год
set_stat('d');

function set_stat( $time_limiter = 'd' ) {
 
  switch( $time_limiter ) {
   case 'd':
     // Day
     $start_stamp = mktime( date("H"), date("i"), date("s"), date("n"), date("j")-1, date("Y") );
     $field = 'day_stat';
     break;
   case 'w':
     // Week
     $start_stamp = mktime( date("H"), date("i"), date("s"), date("n"), date("j")-7, date("Y") );
     $field = 'week_stat';
     break;
   case 'm':
     // Month
     $start_stamp = mktime( date("H"), date("i"), date("s"), date("n")-1, date("j"), date("Y") );
     $field = 'month_stat';
     break;
   case 'y':
     // Year
     $start_stamp = mktime( date("H"), date("i"), date("s"), date("n"), date("j"), date("Y")-1 );
     $field = 'year_stat';
     break;
    
  } // End switch
 
  $end_date = date('Y-m-d');
  $start_date = date('Y-m-d', $start_stamp );
 
  echo "From " . $start_date . " to " . $end_date . "<br>";
 
  $ga = new gapi(ga_email,ga_password); // Создаем экземпляр класса доступа к данным
 
  $start_index = 1;
  $max_results = 500;
 
  $filter = null; // Поддерживает регэкспы. Я не использую, но можно сделать дополнительно фильтр, чтоб не грузить лишние данные
 
  // Сам запрос к GA
  while( $ga->requestReportData(ga_profile_id, array('pagePath'), array('pageviews','uniquePageviews'), array('-Pageviews'), $filter, $start_date, $end_date, $start_index, $max_results) ) {
   
   $request = $ga->getResults();
   foreach( $request as $page ) {
     if( preg_match( "/^\/(\d+)\.html$/is" , $page, $matches ) ) { // Это регэксп можно поменять для другой структуры URL
      
      $art_id = $matches[1]; // А тут следует поменять, если ID из URL не совпадает с ID в базе
      
      // Обновляем буферную таблицу
      mysql_query( "UPDATE art_stat
             SET "
. $field . " = " . $page->getuniquePageviews() . "
             WHERE art_id = "
. $art_id
            );
      
      if( mysql_affected_rows() == 0 ) {
        mysql_query( "INSERT INTO art_stat ( art_id, " . $field . " )
               VALUES ( "
. $art_id . ", " . $page->getuniquePageviews() . " )"
             );
      } // End if
      
     } // End if
    
   } // End foreach
    
   $start_index += $max_results;
    
  } // End while
   
} // End function set_stat

require_once 'end.php'; // Отключение от базы и прочее

?>


* This source code was highlighted with Source Code Highlighter.


Вешаем скрипт на крон, предварительно подготовив, и получаем регулярно обновляемую статистику по материалам у себя на сайте.

Напоследок, приведу пример запроса для получения самых популярных за неделю
SELECT a.id, a.name, s.week_stat AS cnt
FROM art a LEFT JOIN art_stat s ON ( s.art_id = a.id )
ORDER BY cnt DESC


* This source code was highlighted with Source Code Highlighter.


Также указанным способом можно попробовать оценить убывание/возрастание пользовательского интереса к конкретным материалам сайта и прочие сопутствующие параметры.

P.S. Это первый пост, так что прошу строго не судить