Hopefully you have all read my short tutorial on PHP and OOP, if not don’t worry too much, you should be fine. We will be covering the basic usage of the WhosOnline class that I created a while back and is pretty popular. I figure I need to get some more info out here to explain it a little better.
Lets start with how it works! First of all, no online counter is 100% accurate. Right now while I am writing this, I am still considered “Online”, but I am not interacting with the server in any way. Lets break it down further. When you access a webpage, the server sends the runs the script you called, and sends you the proper HTML. The server is done with you from that point on, unless you access another script on the webpage and get more info from the server. If I head over to fmylife.com, I type http://www.fmylife.com into my browser and hit enter. Their server runs a script that gets me all the latest FMLs and leaves me alone. I take my sweet time reading and laughing at the 20 or so on the first page, maybe 10 minutes. I would consider myself “online” during that time because I was actively reading postings, but the server doesn’t know that, it only saw me load the page 10 minutes ago. For all it knows, I moved on to another page on a completely different site. So here is the problem, how does the server know IF you are actually online? It doesn’t. So how do we know?!?!?
Basically we just have to keep track of who visited the website and the times they visited. The we can say whether or not they are online. If I have a website with news articles, I would probably say that visitors tend to remain on one page for 20 minutes. If it was a short site, maybe a gaming site, or even a forum, most people will stay on the same page for 5 minutes, 10 minutes max. So anyone that accessed the site in the last 10 minutes would be considered “online” to the server, and we could show it on all of our pages.
So that is how it all works. We have a script that needs to be run on all pages. What it does is checks to see if you have an active session stored in the database. If you do it will just update it with the current time, otherwise it will create a new entry. After it updates the current viewer, it will go through and delete all the “old” and “offline” people (those who have idled 10-15 minutes or so). It does this simply so you don’t fill up your database with thousands of different users and times, which will ultimately slow down your page loading time. Then you just need to have it display who is online!
Lets get down to the nitty-gritty, or the code. The code is well documented/commented and most php editors will give you clues on how to use the functions and classes. First and foremost, you need to be sure you have a mysql database that you can create a table on. The program will create the table automatically if it is allowed, if not you will have to create one for it. There is simply 3 fields, the “sid” or session id. This a “varchar” and I put 100 characters. The next field is the “time” which is an “int” and I gave it 100 as well for the length. The last field is the “users” which is a “varchar” length 100 as well. Even if you don’t plan on using the users, it still needs to be there. If it isn’t, you will get errors galore.
Secondly, we need sessions! A session is like a global variable that works on EVERY page of the server. I can save a persons age on 1 page and access it on the next page quickly and easily. Most people that have some sort of login will use sessions to store whether or not someone is online, and give them access to certain areas if they have a high enough clearance level. All we need a session for is to keep track of them as they surf, so we don’t say 100 people are online if 1 person visits 100 different pages real quick.
So lets get started, first we will start our session and call our class, and then update the table.
1 2 3 4 5 6 7 8 9 10 | <?php include("whosonline.php"); session_start(); //Create your connection $who=new WhosOnline('localhost','root','','myDB'); //Set up the table you will use $who->TableSet("online"); //Update the table with the new data $who->Update(); ?> |
In line 2, we include the code with our class and functions.
In line 3, we start our session (this is typically done at the very beginning, because starting it later on can cause problems)
In line 5, we call our class and store it in the variable $who.
- localhost – The mysql server (typically localhost)
- root – Your mysql username
- ‘ ’ – Your mysql user password goes here
- myDB – The database name we will connect to
In line 7, we set the name of the mysql table we will use. If that table doesn’t exist, one will be automatically created UNLESS we change it to $who->TableSet("online", false);. By changing it to false, we restrict the function from creating a table if one doesn’t exist. This might be beneficial if you have a limited number of tables/space and have already set one up for it.
In line 9 we simply update the table. This is where it updates the user and deletes idlers.
This previous set of code is what we would include on the header of EVERY page that we want to keep track of. Failure to include it will make people go “offline” if they visit certain pages lacking this intro. Even if you don’t plan on displaying the data, you might still want to include it.
The next part is simply displaying the data. There are 3 ways to do it. The first, and most simple way is to use the Data() function:
1 2 3 4 5 6 7 8 9 10 11 12 | <?php include("whosonline.php"); session_start(); //Create your connection $who=new WhosOnline('localhost','root','','myDB'); //Set up the table you will use $who->TableSet("online"); //Update the table with the new data $who->Update(); echo $who->Data(); ?> |
This is give us the COUNT of active people on our server. You can store it and display however you want.
The second way to display it is with graphical images. I am reminded of those old school counters everyone had on their Geocities webpages, and threw that in just in case people still wanted to do that. In order for that to work, you have to set the images 0-9. You can do a quick google search of numbers and pull up a bunch of different styles to use. I found stupid looking circle ones to use:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php include("whosonline.php"); session_start(); //Create your connection $who=new WhosOnline('localhost','root','','myDB'); //Set up the table you will use $who->TableSet("online"); //Update the table with the new data $who->Update(); $who->SetImage(0,"http://wikitriz.editme.com/files/Home/Number0.gif"); $who->SetImage(1,"http://wikitriz.editme.com/files/Home/Number1.gif"); $who->SetImage(2,"http://wikitriz.editme.com/files/Home/Number2.gif"); $who->SetImage(3,"http://wikitriz.editme.com/files/Home/Number3.gif"); $who->SetImage(4,"http://wikitriz.editme.com/files/Home/Number4.gif"); $who->SetImage(5,"http://wikitriz.editme.com/files/Home/Number5.gif"); $who->SetImage(6,"http://wikitriz.editme.com/files/Home/Number6.gif"); $who->SetImage(7,"http://wikitriz.editme.com/files/Home/Number7.gif"); $who->SetImage(8,"http://wikitriz.editme.com/files/Home/Number8.gif"); $who->SetImage(9,"http://wikitriz.editme.com/files/Home/Number9.gif"); echo $who->DisplayImages(); ?> |
If I had 124 people online at once, it would show the image for 1, then 2, then 4. In order to display the images, you must use DisplayImages();
The final way requires a bit more work, but it will show WHO is actually online.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php include("whosonline.php"); session_start(); //Create your connection $who=new WhosOnline('localhost','root','','myDB'); //Set up the table you will use $who->TableSet("online"); //Update the table with the new data $who->Update(); //For usernames, they must be a variable somewhere. $_SESSION['username']="bob"; $who->UpdateUser('username','SESSION'); //Update it again (add the username to the session id) $who->Update(); //Show data as an array print_r($who->Data("ARRAY")); ?> |
In line 12 we set the session variable for the user. This is typically done on a page when they log in, but I put it here to demonstrate. Whatever the username is stored as, we have to set it in the class to get it updated in the database. So in this case, if the variable was stored in the space ‘username’ in the session array, we will update our class in line 13.
Line 13:
- UpdateUser – The function that tells the class who this user is.
- ‘username’ – Where the info is stored in the session array
- ‘SESSION’ – To let the class know to search the session array for that key and then update the class.
Instead of a session variable, you may pull your info from a database and can type $who->UpdateUser($user,'STRING'); where it will simply update the username with a specific variable rather than a value in the session array.
Line 15, we update again, make sure the user name is now associated with his session in the database, so he isn’t just a “Guest” anymore.
Line 17, we use the Data() function again, but this time we want it to return a little more than numbers, so we type “ARRAY” inside to have it return an array with all the data. The array has 4 parts, 0-xxxx numbers are the names of online members. If they are guests, it excludes them from this process. In the ‘count’ key, we have stored the TOTAL number of people online. In the ‘members’ key, we stored how many MEMBERS were online. In the ‘guests’ key, we stored how many GUESTS were online. I sometimes see something like this:
| Total online: | 14 |
| Guests: | 10 |
| Members: | 4 |
| Bob, Jo, Steve, Ruben | |
By using the array, you can display all this pretty easily:
$data=$who->Data("ARRAY"); echo "<table><tr><td>Total online:</td>"; echo "<td>$data[count]</td></tr>"; echo "<tr><td>Guests:</td>"; echo "<td>$data[guests]</td></tr>"; echo "<tr><td>Members:</td>"; echo "<td>$data[members]</td></tr>"; echo "<tr><td colspan="2">"; for($a=0;$a<$data[members];$a++){ echo $data[$a]." "; } echo "</td></tr></table>";
Well we did it, we covered the basics. That last little bit was a little rough, with the user names and such, but I think it is pretty self explanatory. There are several advance features that you can customize and use.
One of my favorites and most important is the idle and delete time. To set this, simply set it like a regular variable. Keep in mind it is in SECONDS, so 5 minutes is 300, 10 is 600, 20 is 1200. By default, you are an active member for 10 minutes, and deleted from the database at 20 minutes. If you want to adjust this, simply type: $who->idletime=300; $who->deletetime=600;
Any of the variables can be set in the class itself to make it easier, or by the script calling the class without using the functions. I am planning on updating it a little more in the future to give a few more customizations. If there is anything else you would like to see, let me know. Thanks!
Notice: Undefined variable: sid in C:\wamp\www\theacademy\whosonline.php on line 340
now I have to wonder, is it worth debugging or not.
I added a : if(isset($sid)) to wrap “if(count($sid)>0)…” statement and error went away.
I guess we’ll see if it is working as intended…….?
Yeah I wasn’t 100% accurate with the declaration of variables/variable checking. I have error reporting turned off on my personal server cause I am kinda lazy. Thanks tho. I will update it.
Hey. If I created a special account for you on my hosting server, would you help install the script on my site, please, the site is being ran by my friend and I so far, I’m 16 and he’s 15 years-of-age. I have already created a membership system using a simple tutorial, and I was wondering if you could use the components from it in the Who’s Online script, to where the members that are shown, are the ones currently online.
I updated the code to use the mysqli extension instead of the older mysql connection.
_construct($host,$user,$password,$database);
return;
}
/**
* WhosOnline::_construct($host, $user, $password, $database [,$table] [,$autoupdate])
*
* This creates the database connection and is created
* by simply typing:
*
* $whosonline = new WhosOnline('localhost','root','','epco');
*
* By utilizing $table and $autocomplete, you do not need to WhosOnline::Update()
*
* @param string $host MySQL Host (localhost)
* @param string $user MySQL database user
* @param string $password MySQL user password
* @param string $database MySQL database
* @param optional string $table MySQL table
* @param optional bool $autoupdate
* @return null Always null
*/
function _construct($host,$user,$password,$database,$table='',$autoupdate=false)
{
$this->mysqlhost=$host;
$this->mysqluser=$user;
$this->mysqlpass=$password;
$this->mysqldatabase=$database;
$this->Connect();
if($table!='' && $autoupdate==true)
{
$this->TableSet($table);
$this->Update();
}
return;
}
/**
* WhosOnline::Connect()
*
* Connects to a mysql database and stores the connection. MySQL
* variables must be set prior to connection, either through
* WhosOnline::_construct() or by setting individual variables
*
* @return null Always null
*/
function Connect()
{
/*
*
*/
try {
$this->dbh = new mysqli($this->mysqlhost, $this->mysqluser, $this->mysqlpass, $this->mysqldatabase);
if (mysqli_connect_errno()) {
//could not connect to db
echo "ERROR: Could not open connection to database";
exit;
}
}catch( Exception $exception ){
echo $exception->getMessage();
}
/*
$this->dbh = @mysql_connect($this->mysqlhost,$this->mysqluser,$this->mysqlpass,true);
//$this->dbh = new mysqli($this->mysqlhost,$this->mysqluser,$this->mysqlpass,$this->mysqldatabase);
if (!$this->dbh) {
$this->Error('Could not connect to the database. Please check your connection settings.');
$this->Error("Host: ".$this->mysqlhost.", User: ".$this->mysqluser.", Pass: ".$this->mysqlpass);
}
if($this->quit)
return;
if(!@mysql_select_db($this->mysqldatabase,$this->dbh))
$this->Error('Invalid database. Possibly typo or user does not have privileges on that database');
*/
return;
}
/**
* WhosOnline::TableSet($table, $create=true)
*
* Checks for the table. If it doesn't exist it will create the
* table if $create is true, otherwise it will return an error.
*
* @param string $table MySQL table where data is stored
* @param bool $create If true, a new table will be created, else echo MySQL error
* @return null Always null
*/
function TableSet($table, $create=true)
{
if($this->quit)
return;
$this->mysqltable=$table;
$tables = array();
$handle =$this->dbh;
$result = $handle->query("SHOW TABLES FROM ".$this->mysqldatabase);
//$query = @mysql_query("SHOW TABLES FROM ".$this->mysqldatabase,$this->dbh);
while ($row = $result->fetch_array()) {
$tables[] = $row[0];
}
if(!in_array($table,$tables) && $create==true)
$this->CreateTable();
else if(!in_array($table,$tables))
$this->Error('Table not found in database.');
return;
}
/**
* WhosOnline::CreateTable()
*
* Creates a MySQL table to store the data.
*
* @return null Always null
*/
function CreateTable()
{
$query="CREATE TABLE ".$this->mysqltable." (sid varchar(100),time int(100), user varchar(100))";
$handle =$this->dbh;
$result = $handle->query($query);
if(!$result)
$this->Error('Unable to create table.');
return;
}
/**
* WhosOnline::Error($message,$mysql)
*
* Displays an error message. If $bail is set to true, it will close the class.
* If $die is set to true, it will terminate the PHP display
*
* @param string $message Error message to be echoed
* @param string $message Error from mysql
* @return null Always null
*/
function Error($message,$mysql='')
{
if($this->die && $this->mysqlerrors)
die($mysql);
else if($this->die)
die($message);
if($this->mysqlerrors)
echo $mysql;
else
echo $message;
if($this->bail)
$this->quit=true;
return;
}
/**
* WhosOnline::DisplayMysqlErrors()
*
* When called, it will turn on mysql error display
*
* @return null Always null
*/
function DisplayMysqlErrors()
{
$this->mysqlerrors=true;
return;
}
/**
* WhosOnline::_destruct()
*
* Class destructor
*
* @return bool Always true
*/
function _destruct()
{
return true;
}
/**
* WhosOnline::Update()
*
* Update the users online
*
* @return null Always null
*
*/
function Update()
{
if($this->quit)
return;
$sid = session_id();
$query="SELECT * FROM ".$this->mysqltable." WHERE sid='$sid'";
$time=time();
$handle =$this->dbh;
$result = $handle->query($query);
//$rows= $result->fetch_array();
$size = $result->num_rows;
//$rows=mysql_num_rows(mysql_query($query,$this->dbh));
if($size!=0)
$query2="UPDATE ".$this->mysqltable." SET time='$time', user='".$this->username."' WHERE sid='$sid'";
else
$query2="INSERT INTO ".$this->mysqltable." (sid,time,user) VALUES ('$sid','$time','".$this->username."')";
$result2 = $handle->query($query2);
if(!$result2)
$this->Error('Error updating the user database.');
$this->Delete();
return;
}
/**
* WhosOnline::Data($return = 'INT')
*
* Returns the number of users considered "Online".
* If $return = 'ARRAY', an array of user names will be returned.
*
* @return int $users The number of people online
* @return array $online An array with the individual people online
*/
function Data($return = 'INT')
{
if($this->quit)
return;
$now=time();
$load=(int)$now-$this->idletime;
$query = "SELECT * FROM ".$this->mysqltable;
$handle =$this->dbh;
$result = $handle->query($query);
//$result=mysql_query($query,$this->dbh);
$users=0;
$members=0;
$guests=0;
$online=array();
while($row=$result->fetch_array())
{
if((int)$row['time']>$load)
{
if($row['user']!='Guest')
{
$online[]=$row['user'];
$members++;
}else
$guests++;
$users++;
}
}
$online['count']=$users;
$online['members']=$members;
$online['guests']=$guests;
if($return=="INT")
return $users;
else
return $online;
}
/**
* WhosOnline::DisplayImages
*
* Like WhosOnline::Data(), displays the number of users online
* but formatted a user defined pictures.
*
* @return string $output A html string with the digits represented by images
*/
function DisplayImages()
{
if(count($this->images)!=10)
$this->Error('Only '.count($this->images).' images defined.');
if($this->quit)
return;
$now=time();
$load=(int)$now-$this->idletime;
$query = "SELECT * FROM ".$this->mysqltable;
$handle =$this->dbh;
$result = $handle->query($query);
//$result=mysql_query($query,$this->dbh);
$users=0;
while($row=$result->fetch_array())
{
if((int)$row['time']>$load)
$users++;
}
$array=str_split($users);
$output='';
foreach($array as $digit)
{
$output.="images[$digit]}'>";
}
return $output;
}
/**
* WhosOnline::Delete()
*
* Deletes users who have "idled" to long from the database
*
* @return null Always null
*/
function Delete()
{
$now=time();
$load=(int)$now-$this->deletetime;
$query = "SELECT * FROM ".$this->mysqltable;
$handle =$this->dbh;
$result = $handle->query($query);
//$result=mysql_query($query,$this->dbh);
$count=0;
$sid = array();
while($row=$result->fetch_array())
{
if((int)$row['time']0)
{
$todelete=implode(" OR ",$sid);
$del = "DELETE FROM ".$this->mysqltable." WHERE $todelete";
$handle->query($del);
//mysql_query("DELETE FROM ".$this->mysqltable." WHERE $todelete");
}
return;
}
/**
* WhosOnline::SetImage($int,$src)
*
* Sets images to be displayed by counter if WhosOnline::ImageDisplay=true;
*
* @param int $int The number
* @param string $src Location of image
* @return null Always null
*/
function SetImage($int,$src)
{
if(is_int($int) && $int=0)
{
$this->images[$int]=$src;
}
return;
}
/**
* WhosOnline::UpdateUser($sessionvar, $type)
*
* Updates WhosOnline::username to match the session variable that is provided.
* $type indicates if the variable is in the session array or just another string.
*
* @param string $sessionvar Location of username in $_SESSION array
* @param string $type Either "SESSION" or "STRING"
* @return null Always null
*/
function UpdateUser($sessionvar, $type = "SESSION")
{
if(!empty($sessionvar) && array_key_exists($sessionvar,$_SESSION))
$this->username=$_SESSION[$sessionvar];
return;
}
}
?>
Nice, I like it. I don’t use mysqli… yet. I actually use a database class that works wonders. I should probably learn mysqli as it will replace mysql come php 6 (or so I have heard).