Detecting Users Online

Page 1 - Recording the User

Skip to navigation

Top Secret
Jul
29

After recently having seen a way of showing the number of people currently visiting your site by recording IP address I thought I'd demonstrate my own way of doing it that also includes the ability to show which users online, and number of users/guests online.

An article recently submitted to dzone titled "Creating a Users Online Script using PHP" by mikebernat.com had some sample code that would record a users ip address and the timestamp of loading the page whenever a page was loaded. This same function would then remove old records that were older than the provided timeout and then returned an integer containing the number of people currently visiting the site. This made me think maybe it would be a good idea to demonstrate how to do this with users and guests instead rather than a "there are x people visiting this site".

For people using Wordpress, this can be easily achieved without doing any coding for yourself and just adding the UserOnline (can be found on the page by scrolling down to WP-UserOnline). This plugin will show how many users are currently online, how many guests are currently visiting the site, how many bots are crawling the site, and when the most number of visitors at any one time was.

In this example, we will assume that in the case of users, they have already been authenticated, and that there is a session variable recording the username of who is signed in. Now, when a visitor access the page a function will be called that will add the username and a timestamp to the database, or their IP address if they are a guest.

define("VISIT_TIMEOUT", "600");
// a variable called db already has connected to
// the database successfully

function trackUser()
{
   global $db; 
   
   $name = "";
   if(isset($_SESSION['username'])) {
      // user is logged in so track the username
      $name = $_SESSION['username'];
   } else {
      // user is not logged in so track the IP
      $name = $_SERVER['REMOTE_ADDR'];
   }

   $time = time();

   // check if user is already listed
   $query = "SELECT COUNT(*) AS total FROM `userOnline` ".
                 "WHERE `title`='$name';";
   $result = @mysql_query($query, $db);
   if($result = @mysql_fetch_array($result)) {
      $count = $result['total'];
   } else {
      // Could not get a record from the result, so must be 0
      $count = 0;
   }
   
   // If already visitor then update, otherwise add them
   if($count > 0) {
      $query = "UPDATE `userOnline` SET `timestamp`='".$time.
                 "' WHERE title='$name';";
   } else {
      $query = "INSERT INTO `userOnline` (`title`, `timestamp`) ".
                 "VALUES ('$name', '$time');";
   }
   @mysql_query($query, $db);

   // Cleanup old visits
   $query = "DELETE FROM `userOnline` WHERE `timestamp` <= '"
      .($time-VISIT_TIMEOUT)."';";
   @mysql_query($query);
}

The above code when called will check the database to see if the user was already visiting the site (but has now either refreshed the page or moved on to another) and will then update their existing record, or if they are a new visitor it will add them to the table. As mentioned earlier it is the Username or the IP address that is recorded depending on them being logged in. As with the code Mike Bernat did on his site, this version will also tidy up expired visits. If we wanted to track people on a specific page of the site then we would have another field in the table that corresponds to the page and is populated with the value of $_SERVER['PHP_SELF'].

Please note that due to the changes to timestamps in MySQL 5.0, the timestamp field is a TINYTEXT field containing a UNIX timestamp rather than it being a timestamp field to avoid conversion issues.

TIMESTAMP columns are displayed in the same format as DATETIME columns. In other words, the display width is fixed at 19 characters, and the format is YYYY-MM-DD HH:MM:SS.