Счетчик онлайн посетителей на сайте

Счетчик онлайн посетителей на сайте

Друзья!

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

Первым делом создадим новую базу с именем “count” и типом utf8_general_ci. Теперь перейдем к теории.

Теория: каким образом считается онлайн?

Одна из самых грамотных техник, которая существует на данный момент, состоит в следующем:

  1. Создается таблица online c количеством столбцов = 3. Первый столбец это id (тип int, длина 11, индекс PRIMARY, A_I — автоинкремент),
    второй lastvisit (тип int, длина 11), третий ip (тип VARCHAR, длина 15, ). В поле lastvisit будет храниться дата посещения пользователя сайта в формате timestamp.
    Когда человек зайдет к нам на сайт, то мы сохраним дату его последнего визита и ip адрес. Из этой таблицы мы будем тянуть все данные, например,
    количество онлайн за последний час;
  2. Достается ip пользователя через суперглобальный массив SERVER;
  3. Проверяется: нет ли уже такой записи об этом пользователе, чтобы каждый раз её не дублировать;
  4. Если такой пользователь уже найден, то мы его обновляем, но это будет сильным ударом по производительности.
    Поэтому в скрипте используется технология — куки, которая позволит обновлять данные в базе через заданный интервал времени.
  5. Для работы с куки используется готовый класс CookieManager, в котором есть 4 метода. Метод store – сохраняет данные в куки.
    Stored – проверяет есть куки или нет. Read – возвращает данные. Delete – удаляет куки, если это требуется.

Практика: листринг скрипта

    
    require 'cookies.php'; // подключаем класс CookieManager
	require 'rb.php'; // подключаем библиотеку ReadBeanPHP
	R::setup( 'mysql:host=127.0.0.1;dbname=count','root', '' );  // подключаемся к базе данных

	if ( !R::testconnection() )
	{
			exit ('Нет соединения с базой данных');
	}

	$cookie_key = 'online-cache';
	
	// Достается ip пользователя через суперглобальный массив SERVER
	$ip = $_SERVER['REMOTE_ADDR']; 
	
	// Проверяет нет ли уже такой записи об этом пользователе, чтобы каждый раз её не дублировать
	$online = R::findOne('online', 'ip = ?', array($ip)); 

	if ( $online )
	{
		$do_update = false;
		// Если такой пользователь уже найден, то мы его обновляем,
		// но это будет сильным ударом по производительности, поэтому использует куки
		if ( CookieManager::stored($cookie_key) )
			{
				$c = (array) @json_decode(CookieManager::read($cookie_key), true);
				if ( $c )
				{
				    //обновляем данные в базе каждые 5 минут
					if( $c['lastvisit'] < (time() - (60 * 5)) ) 
					{
						$do_update = true;
					}
				} else
				{
					$do_update = true;
				}

			} else{
					$do_update = true;		
			}
			if ( $do_update )
			{
			        // Сохраним в куки дату последнего обновления 
			        // информации о посещении пользователя
					$time = time();
					$online->lastvisit = $time;
					R::store($online);
					CookieManager::store($cookie_key, json_encode(array(
						'id' => $online->id,
						'lastvisit' => $time)));
					
			}

	} else{
		// Если пользователь не найден, то мы его добавим
		$time = time();
		$online = R::dispense('online');
		$online->lastvisit = $time;
		$online->ip = $ip;
		R::store($online);
		CookieManager::store($cookie_key, json_encode(array(
			'id' => $online->id,
			'lastvisit' => $time)));
		// json_encode мы делаем потому что в куки нельзя хранить структуры, 
		// в отличии от сессии, а можно хранить только строки
	}

    // Выводим количество онлайн за последний час
	$online_count = R::count('online', "lastvisit > " . ( time() - (3600) ))
	
	// конец

Класс для работы с куки CookieManager

    
class CookieManager {
 
    public function __construct() {
        //empty one
    }
 
    static public function store($key, $value, $expire = false, $path = '/',
    $domain = 'current', $secure = 0) {
        if ($domain == 'current') {
            $domain = $_SERVER['HTTP_HOST'];
        }
        if (!$expire) {
            $expire = time() + (3600 * 24);
        }
        setcookie($key, $value, $expire, $path, $domain, $secure);
        return true;
    }
 
    static public function read($key) {
        if (isset($_COOKIE[$key])) {
            return $_COOKIE[$key];
        } else {
            return false;
        }
    }
 
    static public function stored($key)
    {
        return isset($_COOKIE[$key]);
    }
 
    static public function delete($key, $value = '', $expire = 1, $path = '/',
    $domain = 'current', $secure = 0) {
        if ($domain == 'current') {
            $domain = $_SERVER['HTTP_HOST'];
        }
        setcookie($key,$value,$expire,$path,$domain,$secure);
        return true;
    }
 
}

Урок был создан на основе видео: