Creating a “Who’s Online” script with PHP
(Page 1 out of 2)Introduction
In this tutorial I will show you how to create your own "Who's Online" script, which is often found on message boards and other community scripts. We will first create a really simple script, and after that add a few more features like the location of each visitor. But first, let me explain how our "Who's Online" script is going to work.
Our script will store a visitor's IP address and last active timestamp in a database, and update it every time the visitor requests one of our pages. The script will actually be a web bug, and run completely in the background. If you want to know more about web bugs, have a look at this SitePoint Blog entry by Harry Fuecks, but in a nut shell it's a small 1x1 image that actually executes PHP, and returns an image. So all our pages will point to a PHP file, like so:
And the whosonline.php file will execute some code, and return a 1x1 gif image. Let's get started with creating a simple version of our "Who's Online" script.
A simple version
Our web bug has to do four things:
- Check if a visitor has already been 'registered'
- Either insert a new visitor or update an existing visitor
- Remove all old visitors who are no longer 'online'
- Serve a 1x1 GIF image, and make sure the web bug doesn't delay the calling page
The first three things are pretty easy, and the following database scheme:
`onlineid` int(5) NOT NULL AUTO_INCREMENT,
`ipaddress` varchar(255) NOT NULL DEFAULT '',
`lastactive` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`onlineid`)
) TYPE=MyISAM AUTO_INCREMENT=0;
With the following code does exactly what we want:
include ('mysql.php');
# Timeout - how long should it take before visitors are no longer 'online'? (in minutes)
define ('TIMEOUT', 20);
// Check if visitor is already in the table
$ipaddress = ss($_SERVER['REMOTE_ADDR']);
$lastactive = time();
$intable = $db->query_first ("SELECT onlineid FROM online WHERE ipaddress = '$ipaddress'");
if ($intable == false) {
// Insert new visitor
$db->query ("INSERT INTO online (ipaddress, lastactive) VALUES ('$ipaddress', $lastactive)");
} else {
// Update exisiting visitor
$db->query ("UPDATE online SET lastactive = $lastactive WHERE ipaddress = '$ipaddress'");
}
// Remove any inactive visitors
$inactive = time()-(60*60*TIMEOUT);
$db->query ("DELETE FROM online WHERE lastactive < $inactive");
?>
(Note that you can get the 'mysql.php' file here)
I don't think it needs any explanation, as it's fairly easy to understand. The only thing I'd like to mention is that to know which visitors should be removed, the script first calculates what the time was 20 minutes ago (which is the timeout time I've set), and any visitor whose last active time is earlier than that is no longer considered active
The only thing that's missing from the above is serving the 1x1 GIF image, and making sure the image doesn't delay anything, and that's actually quite important. Although the above code probably doesn't have any noticeable delay, it's always a good thing to optimize your code as much as possible (within reason).
If you've read the SitePoint blog entry about web bugs, you will have seen that they've given the code to make sure the image doesn't delay anything. What they basically do is first send out the image, close the connection with the browser, and then actually start the real work, which in our case is the code above. It looks something like this:
ob_implicit_flush(TRUE);
// keep running after browser closes connection
@ignore_user_abort(true);
sendGIF();
function sendGIF(){
$img = base64_decode('R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAEALAAAAAABAAEAAAIBTAA7');
header('Content-Type: image/gif');
header('Content-Length: '.strlen($img));
header('Connection: Close');
print $img;
// Browser should drop connection after this
// Thinks it's got the whole image
}
This code first makes sure the image gets sent out, and then sets the ignore_user_abort option to true, which causes the script to run on, even after the connection is closed, which is exactly what we want. It then sends the GIF image, using some standard headers and data.
If you combine the above two code snippets together (the second snippet first, then the first snippet), and we've got our 'whosonline.php' file.
All we need now is some simple code to display everyone who's online, and we've got ourselves a simple "Who's Online" script. I'm using the following code to display who's online:
include ('mysql.php');
// Include counter (I'm only using one page)
echo '';
echo 'Currently Online:
';
$online = $db->sql_query ("SELECT onlineid, lastactive, ipaddress FROM online ORDER BY lastactive");
if (count($online) == 0) {
echo 'Nobody';
die();
}
echo ' echo ' echo '';
';
echo 'IP Address Last Active ';
foreach ($online as $visitor) {
echo '';
';' . $visitor['ipaddress'] . ' ';
echo '' . date('g:i:s', $visitor['lastactive']) . ' ';
}
echo '
?>
Let's have a look at adding a new feature: how to include the location of the visitor.
December 19th, 2005 at 9:32 pm
[…] Otra cosa interesante fue la de un script para ver “quien esta online”, que siempre es util. […]
February 5th, 2006 at 7:38 am
Your timeout removal is buggy, if you just want to delete users with inactivity of 15 minutes, all entries with (last_activity
February 5th, 2006 at 7:38 am
Sorry, but it was to early and no edit-function is available. I meant 60*TIMEOUT not 15*TIMEOUT ;-)
April 5th, 2006 at 5:55 am
$inactive = time()-(60*60*TIMEOUT);
change to
$inactive = time()-(60*TIMEOUT);
May 22nd, 2006 at 2:38 am
And what about if we want to display the name of my logged-in members instead of their Ip’s?
May 24th, 2006 at 12:39 am
You have to change
echo ‘’ . $visitor[’ipaddress’] . ‘’;
to
echo ‘’ . $visitor[’username’] . ‘’;
this way you see which user is online.
June 22nd, 2006 at 11:20 pm
Nice… I was thinking of eventually adding Forums when I turn my site into a real site and this will be very helpful…
Thanks guys…
June 22nd, 2006 at 11:45 pm
[…] In this tutorial I will show you how to create your own “Who’s Online” script, which is often found on message boards and other community scripts. We will first create a really simple script, and after that add a few more features like the location of each visitor.read more | digg story […]
June 23rd, 2006 at 12:00 am
Not bad. Although a LOT longer than it could be. Try to be simpler. User online -> Add to DB. Cron removes from DB every 5 minutes if added within last 15 minutes. Display countof visitors table. Done.
June 23rd, 2006 at 1:04 am
Way to use to much code. I prefer my approach. (Which is in the website link)
June 23rd, 2006 at 3:45 am
“if (count($online) == 0) {
echo ‘Nobody’;
die();
}”
Sorry to tell you that adding that part of code is stupid. If someone is browsing a page, let it be an user or a bot, then there MUST be at least 1 user. I don’t know if it’s just me, but I hate useless code. Correct me if I am wrong though.
June 23rd, 2006 at 4:03 am
Hey,
Is it possible to incoporate this script into my new website
www.Blogsitesreviews.com
(Made for bloggers by a blogger:)
June 23rd, 2006 at 6:32 am
Using REMOTE_ADDR for user identification is very very very problematic.
Users behind firewalls will all share an IP.
AOL Users change IP more often than drummers change their underwear.
This is probably a Bad Idea.
June 23rd, 2006 at 7:10 am
Don’t use disk access… Change your create table command to use Type=Hash or Memory. This will kill a DB server on useless tasks under load.
June 23rd, 2006 at 9:08 am
Maybe it would make more sense to use a “insert into replace” or “insert on duplicate update”. That way you can drop the first select.
June 23rd, 2006 at 10:18 am
[…] read more | digg story […]
June 23rd, 2006 at 3:27 pm
[…] In this tutorial I will show you how to create your own “Who’s Online” script, which is often found on message boards and other community scripts. We will first create a really simple script, and after that add a few more features like the location of each visitor. But first, let me explain how our “Who’s Online” script is going to work. | […]
June 26th, 2006 at 1:31 pm
[…] Link […]
June 27th, 2006 at 7:19 am
[…] PHPit - Totally PHP » Creating a “Who’s Online” script with PHP (tags: php tutorial whos online) […]
June 27th, 2006 at 1:04 pm
[…] Yet another “online” script. This time, PHPit.net uses a databese and a very small picture. Later they complicate the script and add location besides the IP. Another thing that you might do (is not included in the tutorial) is using Google Maps API and an IP localization software to show a map with the visitors.read more | digg story […]
June 30th, 2006 at 4:27 am
[…] Creating a “Who’s Online” script with PHP In this tutorial I will show you how to create your own “Who’s Online” script, which is often found on message boards and other community scripts. We will first create a really simple script, and after that add a few more features like the location of eac (tags: PHP Forums) […]
July 5th, 2006 at 1:54 am
[…] http://phpit.net/article/creating-whosonline-script-php/read more | digg story […]