Кто сейчас на сайте?

Протокол HTTP не позволяет устанавливать сессии и, как следствие, не позволяет отслеживать длительность работы посетителя с Web-ресурсом. Единственное, что можно зафиксировать, - это время обращения клиента к ресурсам сервера. После этого посетитель может часами читать загруженную страницу - Web-сервер не может узнать момент прекращения работы посетителя с загруженными страницами. Поэтому будем считать, что посетитель покинул Web-ресурс, если с момента последней загрузки им страницы прошло 20 минут.

Для фиксирования времени обращения посетителей к страницам ресурса создадим таблицу MySQL session, в которой будем хранить имена пользователей и время их последнего обращения к странице.

CREATE TABLE session (
  id_session TINYTEXT NOT NULL,
  putdate DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  user TINYTEXT NOT NULL
) ENGINE=MyISAM;

Таблица содержит три поля:

  • id_session - идентификатор сессии;
  • putdate - время последнего обращения посетителя к страницам сайта;
  • user - имя пользователя.

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

<?php
  // Начинаем сессию
  session_start();
  // Получаем уникальный id сессии
  $id_session = session_id();
  // Устанавливаем соединение с базой данных
  include 'connect.php';
  if ( isset( $_SESSION['user'] ) )
    $user = $_SESSION['user'];
  else
    $user = '';
  // Проверяем, присутствует ли такой id в базе данных
  $query = "SELECT * FROM session
            WHERE id_session = '"
.$id_session."'";
  $res = mysql_query($query);
  if ( $res ) {
    // Если сессия с таким номером уже существует,
    // значит пользователь online - обновляем время его
    // последнего посещения
    if( mysql_num_rows($res) > 0 ) {
      $query = "UPDATE session SET putdate = NOW(), user = '".$user."'
                WHERE id_session = '"
.$id_session."'";
      mysql_query($query);
    } else {
      // Иначе, если такого номера нет - посетитель только что
      // вошёл - помещаем в таблицу нового посетителя
      $query = "INSERT INTO session
              VALUES('"
.$id_session."', NOW(), '".$user."')";
      mysql_query($query);
    }
  } 
  // Будем считать, что пользователи, которые отсутствовали
  // в течении 20 минут - покинули ресурс - удаляем их
  // id_session из базы данных
  $query = "DELETE FROM session
            WHERE putdate < NOW() -  INTERVAL '20' MINUTE"
;
  mysql_query($query);
?>

В начале скрипта при помощи функции session_id() получается текущий идентификатор сессии. Если такой идентификатор отсутствует в таблице session, то происходит добавление новой записи, что эквивалентно приходу на ресурс нового посетителя. Если же идентификатор присутствует в таблице session, следовательно, данный посетитель уже зашел на ресурс и требуется обновить время его посещения и имя на тот случай, если он осуществил авторизацию только сейчас. В конце скрипта происходит удаление всех записей таблицы, время посещения для которых было обновлено более чем 20 минут назад - таким образом фиксируется уход посетителя с ресурса.

Этот скрипт следует подключить при помощи инструкции include ко всем страницам сайта, чтобы отслеживать присутствие посетителя на сайте.

Теперь не составит труда вывести список текущих посетителей:

<?php
  // Устанавливаем соединение с базой данных
  include 'connect.php';
  // Выводим имена всех посетителей, записи о которых имеются
  // в таблице session
  $query = 'SELECT * FROM session';
  $res = mysql_query($query);
  if ( $res ) {
    // Если хоть кто-то есть - выводим список
    if ( mysql_num_rows($res) > 0 )
    {  
      $guests = 0;
      while( $row = mysql_fetch_array($res) )
      {
        if ( empty( $row['user'] ) )
          $guests = $guests + 1;
        else
          $users[] = $row['user'];
      }
      if ( $guests > 0 or isset( $users ) ) {
        echo 'Сейчас на сайте: ';
        if ( isset( $users ) ) echo implode(',', $users);
        if ( $guests > 0 and isset( $users ) ) echo ' и ';
        if ( $guests > 0 ) echo $guests.' гостей';
      }
    }
  } 
?>

Комментариев: 6

  1. leonder:

    $users[] = $row['user']
    забыл запяточку ;-)

    подправил под свой сайт и вроде как неплохо работает…
    но в конце так имхо лучше:

    echo ‘Сейчас на сайте: ‘;
    if ( isset($users) ) echo ‘‘.implode(’, ‘, $users).’‘;
    if ( $guests > 0 && isset( $users ) ) echo ‘. ‘;
    if ( $guests > 0 ) echo ‘Гостей: ‘.$guests;
    echo ‘ (данные за последние 10 минут)’;

  2. admin:

    leonder, спасибо, исправил.

  3. ekimoff:

    1) лучше использовать REPLACE или ON DUPLICATE KEY UPDATE при вставке новой сессии (у тебя даже статья есть про это)
    2) лучше использовать InnoDB вместо MyISAM- т.к. таблица постоянно подвергается чтению/обновлению.

  4. Елена:

    Скажите, пожалуйста, если на сайте нет регистрации и не будет, но хотелось бы знать сколько народу сейчас онлайн. Как можно это сделать?
    За ранее спаибо за ответ.

  5. Дмитрий:

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

Оставьте свой отзыв