Page 1 of 1

get user with active session or ip address

Posted: Fri Sep 04, 2009 1:12 am
by nga
to clarify, in the end i want to get the user ID of all the user who is logged in the website and have an opening window(to the site of course) (like how some forum showings the current online users).

I have no idea on how to do this but after searching the website, there are 2 ways to do this: via IP address and session ID(on how to do this, no site i know meantioned). Could you guys at least give me some pointer?

Re: get user with active session or ip address

Posted: Fri Sep 04, 2009 3:12 am
by AlanG
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.