In today’s Code for Fun section I’ll show you a simple way of displaying the number of online visitors to your site.
The code implements the Template method Pattern and the number of online visitors is saved into a file of your choice.
As you saw in the Template method Pattern article the class structure is very simple and straightforward:
//@ BASE CLASS abstract class AbstractUsersOnline { //@ Define methods that MUST be implemented //@ in all derived classes abstract protected function AddUser(); abstract protected function CheckUsers(); abstract protected function CountUsers(); //@ Retrieve the IP address protected function GetIP() { /*{ TO DO }*/ } /** * ## The Template Method * * Retrieve the number of online users. * @return int */ public function CountOnlineUsers() { $this->CheckUsers(); $this->AddUser(); return $this->CountUsers(); } } //@ DERIVED CLASS class File_UsersOnline extends AbstractUsersOnline { //@ IMPLEMENT ABSTRACT METHODS protected function AddUser() { /*{ TO DO }*/ } protected function CheckUsers() { /*{ TO DO }*/ } protected function CountUsers() { /*{ TO DO }*/ } }
All we have to do now is to implement the defined steps:
/** * abstract class UsersOnline * Defines the course of action */ abstract class AbstractUsersOnline { // Methods that MUST be implemented // in all derived classes abstract protected function AddUser(); abstract protected function CheckUsers(); abstract protected function CountUsers(); /** * @internal * Retrieve the IP address of the visitors. * @return string */ protected function GetIP() { $HCIP = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : '0.0.0.0'; $HXF = isset($_SERVER['HTTP_X_FORWARDED']) ? $_SERVER['HTTP_X_FORWARDED'] : '0.0.0.0'; $HXFF = isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : '0.0.0.0'; $RMAD = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0'; $ipAddress = ($HCIP) ? $HCIP : ($HXF) ? $HXF : ($HXFF) ? $HXFF : ($RMAD) ? $RMAD : '0.0.0.0'; return $ipAddress; } /** * ## Template method * * Retrieve the number of online users. * @return int */ public function CountOnlineUsers() { $this->CheckUsers(); $this->AddUser(); return $this->CountUsers(); } } // >> END CLASS AbstractUsersOnline /** * class File_UsersOnline * * Retrieve the number of online users. Data is saved into a file */ class File_UsersOnline extends AbstractUsersOnline { /** * In minutes, the amount of time a user's session is considered active * @type int */ private $timeout = 5; /** * The full path to the file where the users will be stored * @type string */ private $filePath = ''; /** * Constructor * @triggers E_USER_NOTICE */ public function __construct( $filePath, $timeout = 5 ) { if ( ! is_file($filePath)) { trigger_error('The file: '.$filePath.' was not found nor it could be created!', E_USER_NOTICE); } if ( ! is_readable($filePath)) { trigger_error('The file: '.$filePath.' cannot be read!', E_USER_NOTICE); } if ( ! is_writable($filePath)) { trigger_error('The file: '.$filePath.' needs writing permissions(0755 or 0777)!', E_USER_NOTICE); } $this->timestamp = time(); if (intval($timeout) < 1) { $timeout = 5; } $timeout *= 60; // transform in seconds $this->timeout = $timeout; $this->filePath = $filePath; } /** * Add a new user to the list. * @return boolean */ protected function AddUser() { $data = array( 'timestamp' => $this->timestamp ,'ip_address' => $this->GetIP() ); $content = file_get_contents($this->filePath); if (empty($content)) { $a = array(); array_push($a, $data); file_put_contents($this->filePath, serialize($a), LOCK_EX); } else { $temp = unserialize($content); // prevent duplicate entries foreach( $temp as $entry) { if ($data['ip_address'] == $entry['ip_address']) { // IP exists. return. return false; } } array_push($temp,$data); file_put_contents($this->filePath, serialize($temp), LOCK_EX); } return true; } /** * Check to see if a user's session has expired and remove it from the list. * @return void */ protected function CheckUsers() { if (file_exists($this->filePath)) { $content = file_get_contents($this->filePath); if ( ! empty($content)) { $data = unserialize($content); $numData = count($data); for ($i=0; $i < $numData; $i++) { if (isset($data[$i]['timestamp'])) { if ($data[$i]['timestamp'] < ($this->timestamp - $this->timeout)) unset($data[$i]); } } //@ if any change if (count($data) <> $numData) { file_put_contents($this->filePath, serialize($data), LOCK_EX); } } } } /** * Retrieve the number of online users. * @return int */ protected function CountUsers() { $content = file_get_contents($this->filePath); if (empty($content)) { return 1; } $data = unserialize($content); $temp = array(); for ($i=0; $i < count($data); $i++) { if (isset($data[$i]['ip_address'])) array_push($temp, $data[$i]['ip_address']); } $num = count($temp); // Clean up memory $temp = $content = $data = null; return $num; } } // >> END CLASS File_UsersOnline
Then we have to include the above code in the pages where we want to display the total of visitors:
require 'online-users.php'; /* // USAGE: */ $foo = new File_UsersOnline( 'usersonline.txt' ); // Get the number of online users $onlineUsers = $foo->CountOnlineUsers(); // Display the number of online users echo "<p><em>Online users for the last 5 minutes:</em> <strong>{$onlineUsers}</strong></p>";
That’s all there is to it! If you want to download and use it on your website, follow this link.
Have fun!

Pingback: Display the number of visitors to your website | IP address.co.uk
This really is a little something I must find more information about, appreciate the post.