I'll do better than that. Here's the full working code.
This would be very easily achieved if you are storing sessions in a database. It's not 100% active and can only show the number of logged in users within a specified time frame, such as the last 5 minutes. Assuming your not using a database to store sessions, you can use a database table to store sessions just for the purpose of counting them.
I have a create a table called online_users to store this data. It holds a session id and a unix timestamp (as an int(10) just for convenience).
Code: Select all
---
-- Table structure for table `online_users`
--
CREATE TABLE IF NOT EXISTS `online_users` (
`sessid` varchar(32) NOT NULL,
`timestamp` int(10) NOT NULL,
PRIMARY KEY (`sessid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
I have created a class to handle the users. It catches a user and compares them to the data in the table. If they are not in it, they are added to it. At the end of the script's execution it cleans up and removes expired users.
Be sure to change the two constants at the top to suit your needs.
OnlineUser.php:
Code: Select all
<?php
class OnlineUser {
const TABLE = 'online_users';
const USER_TIMEOUT = 300; // The number of seconds in which a user should be considered active
private $database;
private $users = array();
private $num_users = 0;
public function __construct($sessid) {
global $database;
$this->database = $database;
$this->fetch_all();
if(!$this->check_user_status($sessid)) {
$this->add_user($sessid);
}
}
// Removes users that have expired from the table (at the end of the script)
public function __destruct() {
$this->remove_expired_users();
}
// Reads the table and exports all data into the $users array
private function fetch_all() {
$query = "SELECT * FROM ".self::TABLE;
$result = $this->database->query($query);
$rows = $result->num_rows;
while($rows > 0) {
$this->users[] = $result->fetch_assoc();
$this->num_users++;
$rows--;
}
}
// Searches the users array for the session id (Assume all haven't expired)
private function check_user_status($sessid) {
for($i=0;$i<$this->num_users;$i++) {
if($this->users[$i]['sessid'] == $sessid) {
return true;
}
}
return false;
}
private function add_user($sessid) {
$sessid = $this->database->real_escape_string($sessid);
$current_time = time();
$query = "INSERT into ".self::TABLE." ('sessid','timestamp') VALUES('$sessid','$current_time')";
if($this->database->query($query)) {
// We should add them to the $users array
$this->users[]['sessid'] = $sessid;
$this->users[]['timestamp'] = $current_time;
$this->num_users++;
return true;
}
else {
return false;
}
}
private function remove_expired_users() {
$current_time = time();
for($i=0;$i<$this->num_users;$i++) {
if($this->users[$i]['timestamp'] <= ($current_time + self::USER_TIMEOUT)) {
$this->database->query("DELETE FROM ".self::TABLE." WHERE sessid='".$this->users[$i]['sessid']."'");
}
}
}
// Build the html markup that will be viewable by users
public function build_html() {
$html = '<div>';
$html .= 'There are currently '.$this->num_users.' users online now.';
$html .= '</div>';
return $html;
}
}
?>
The index.php file will show you how this is implemented. You can change the html in the build_html function at the bottom of the OnlineUser class.
index.php:
Code: Select all
<?php
include_once('OnlineUser.php');
// Database Settings
define('HOST','localhost');
define('USER','root');
define('PASS','');
define('NAME','test');
$database = new mysqli(HOST,USER,PASS,NAME);
session_start(); // Starts the session
$sessid = session_id(); // Gets the session id
$online_user = new OnlineUser($sessid);
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<?php
echo $online_user->build_html();
?>
</body>
</html>
<?php exit(); ?>

If you need this modified in anyway, feel free to post below.

Enjoy.