Add new comment
Who's on line?
Ever been to a website and see a "Who's Online" box that said something like, "There have been 3 visitors in the last 15 minutes?" If not, check out ezBoard's, or use this code to add it to your very own site! (requires: PHP and mySQL)
{{UPDATED: June 27, 2003}}
I threw this together for use here on NBrid, but I'm not sure if it will stay. So I'll post it should anyone else care to use it. It helps a lot if you know at least some PHP. If not, you might learn some.
Please note: I changed this since I first posted it to print the names of any members online (PSL), and I reduced the number of mySQL calls.
What you need: A webhost with PHP and mySQL. Other than that you just need this page and a nice text editor (well, and a FTP program to upload a few files to your host).
We use phpSlash (PSL) so I'll explain how this best works with that, but I'll also show how it's done without it. All code will be color coded: light blue is code for both versions, blue is just for PSL users, and red is just for non-PSL users.
First thing to do is setup the mySQL database table. Take the below code and copy it (highlight it and hit ctrl-c, duh) into a text file (Notepad?) called "dump.sql". Most places with mySQL have phpMyAdmin installed so go there next (check in your site's control panel). In the list of databases/tables on the left, click the database you will use (listed in black). It may be something like "yourdomain_com" if you only have one database. (Check with your provider.) Once selected, scroll down on the right to the "Run SQL query/queries" section. Click on 'Browse' by location of text file and select the "dump.sql" you made. Then hit 'Go'.
CREATE TABLE nb_online (
session_id varchar(32) NOT NULL default '',
activity datetime NOT NULL default '0000-00-00 00:00:00',
ip_address varchar(15) NOT NULL default '',
member varchar(60) default NULL,
PRIMARY KEY (session_id),
KEY session_id (session_id)
) TYPE=MyISAM;
INSERT INTO nb_online (session_id, activity, ip_address, member) VALUES ('0000-00-00 00:00:00', '0000-00-00 00:00:00', '0', 'max_record');
Next you need to insert 'magic' code into all of your pages. In phpSlash, add this to the bottom of config.php (right before the end "?>").
$db = pslNew("slashDB");
$member = $auth->auth['dname'];
if (!$member) { $member = $auth->auth['uname']; }
if ($sess->is_registered("nb_online")) {
$q = "UPDATE nb_online SET activity=now(), member='$member' WHERE session_id='$sess->id'";
} else {
$sess->register("nb_online");
$q = "INSERT INTO nb_online (session_id, activity, ip_address, member) VALUES ('$sess->id', now(), '$_SERVER[REMOTE_ADDR]', '$member')";
}
$db->query($q);
For non-PSL users, I still suggest you add it to a 'config.php' (in your base folder, if you don't already have one in use), and then at the top of each actual page put: <?php require "/path/to/config.php"; ?> since this will make any future changes easier (where '/path/to/' is the full/absolute path, or just use "config.php" if all the files are in the same folder). It doesn't have to be named "config.php" either, it can be ANY php file that is included at the top of all your pages. If this is confusing, then just copy the code into the top of all your pages.
I should note for this to work, all your pages you want to moniter need to end in ".php" (unless of course you setup your server to peruse other file extensions for php code).
Another note for non-phpSlash users. This setup uses sessions (PHP 4), so the very first thing at the very top of your page (before ANY html is sent to the users browser) needs to be the "session_start()" line (see below). Either atop the 'config.php' file like it is here (perfered way), or atop all your pages (also remember, ALL php code needs to be somewhere between "<?php" and "?>" tags, not each line but the entire code segment).
<?php
session_start(); //MUST be before any HTML is sent to browser
$db = mysql_connect("localhost", "login", "password");
mysql_select_db("database", $db);
$sess_id = session_id();
if (session_is_registered("nb_online")) {
$q = "UPDATE nb_online SET activity=now() WHERE session_id='$sess_id'";
} else {
session_register("nb_online");
$q = "INSERT INTO nb_online (session_id, activity, ip_address) VALUES ('$sess_id', now(), '$_SERVER[REMOTE_ADDR]')";
}
@mysql_query($q);
?>
Phew. For non-PSL users, you need to replace 'login', 'password', and 'database' (the one you clicked on back in phpMyAdmin) with your mySQL information on lines 5-6.
I suggest testing this out on just one of your pages before you try it on all of them and one small mistake makes your whole site go down.
The next step is how to read this information to show how many are actually online. Here is the code that I suggest you copy into a file called whosonline.php (and into a folder called "online"):
<?php
$_NBO = array (
"login" => "login",
"password" => "password",
"dbname" => "database",
"tblname" => "nb_online",
"timeout" => "15",
"offset" => "0",
);
//connect to mysql
$db = mysql_connect("localhost", $_NBO['login'], $_NBO['password']);
mysql_select_db($_NBO['dbname'], $db);
//get data from table and count number of visitors within 'timeout' minutes
$lmt = time() - ($_NBO['timeout'] * 60);
$q = "SELECT * FROM $_NBO[tblname] WHERE UNIX_TIMESTAMP(activity) >= $lmt OR member = 'max_record' GROUP BY ip_address";
$results_handle = mysql_query($q);
$visitors = mysql_num_rows($results_handle) - 1;
//look through data for the row holding the max record and any online members
while ($row = mysql_fetch_assoc($results_handle)) {
if ($row['member'] == "max_record") {
$max_record = $row['ip_address'];
$date_set = $row['session_id'];
if ($visitors > $max_record) {
$date_set = date("Y-m-d H:i:s", time()-$_NBO['offset']);
$max_record = $visitors;
$q = "UPDATE $_NBO[tblname] SET ip_address='$max_record', session_id='$date_set' WHERE member='max_record'";
@mysql_query($q);
}
}
elseif ($row['member'] && $row['member'] != "nobody" && $row['member'] != "Anonymous") {
$member_list[] = $row['member'];
}
} //you need this line for both PSL and non-PSL users!
$members = count($member_list);
$guests = $visitors - $members;
//about 1 in 100 views (by random) clean database of day old records
mt_srand((double)microtime()*1000000);
$rndom = mt_rand(1, 100);
if ($rndom == 50) {
$expire = time() - 86400;
$q = "DELETE FROM $_NBO[tblname] WHERE UNIX_TIMESTAMP(activity) < $expire AND member != 'max_record'";
@mysql_query($q);
}
//format date_set for output
$date_set = date("g:ia on n/j/y", strtotime($date_set));
//print out who's online ezboard style
if ($visitors == "1") {
$output = "<b>$visitors</b> visitor in the last $_NBO[timeout] minutes";
} else {
$output = "<b>$visitors</b> visitors in the last $_NBO[timeout] minutes";
}
if ($members == "1") { $output .= ": $members Member"; }
else { $output .= ": $members Members"; }
if ($guests == "1") { $output .= " - $guests Guest"; }
else { $output .= " - $guests Guests"; }
$output .= " - $max_record Max (set at $date_set)";
if ($members > 0) {
$member_list = implode(" · ", $member_list);
$output .= "<br><br><i>· $member_list</i>";
}
print $output;
?>
Remember to remove the blue sections if not using PSL. Then just fill out the information at top. Login, password, and database (your mySQL info) are required. Leave 'tblname' as 'nb_online' (unless you really want to use something else). The other options are as follows.
- timeout: timeframe in which to count number of visitors in minutes (I suggest 5 or 15)
- offset: offset from server time in seconds (0=no offset)
A few side notes. You can remove lines 15/16 if you already have a connection to mySQL on your pages (same for lines 5/6 in the first non-PSL code snip). If you know what you're doing, you can edit the code at the end of this file to change how it's shown (currently it mimics ezBoard's style). If you use PSL and don't want user names shown of who's online, remove that last blue section of code.
Garbage collection. A must otherwise your database could get quite big. Already this who's online counter will cause 2-3 mySQL queries, it would only be worse with a big database (by big I mean HUGE though). Above I have it randomly clean the database of old records about once every 100 page views. A few other ways to do this: Setup a Cron (if you can or know how) using the code above (the two lines that connect you to mySQL and the three lines after 'if ($rndom ==50)'). Make a separate page with those lines that you can manually load every so often. Or put it on say your search page so anyone who goes there automatically cleans it for you:)
Finally you are ready to put this on your site, for non-PSL people just add this (always somewhere between a "<?php" and "?>" tag) where you want it to appear on your pages:
<?php include "/path/to/online/whosonline.php"; ?>
For PSL users, create a new block of type 'url'. Then set the URL to the location of whosonline.php (ex: http://www.nbrid.net/online/whosonline.php). Set the expire time to "0". You will also need to turn off caching in config.php. Just change the 1 to a 0 after $JPCACHE_ON (line 275), so $JPCACHE_ON = 0.
Yay! If you need help, just click reply below! There are sure to be other (read: better) ways to do this, and I make no guarantees it will work for you, but... good luck!