Ever wondered how many people are on your website? Do you think Analytics Real-Time shows all of the visitors? If you don’t have any clicks in 5 minutes (which I believe is the timeout of Analytics Real-Time) you won’t be seeing that user in Analytics Real-Time.
This tutorial will help you build an online user script.
You will need:
- MySQL Database
- PHP Server
- User IDs
Create the PHP file for pinging (uop.php). Pinging will not work if userid and url is not posted. It will save userid,url,ip and time to the database. You will need to change highlighted area according to your database name, username and password:
<?php ob_start(); if(!isset($_POST['uid'])||empty($_POST['uid'])||!isset($_POST['url'])||empty($_POST['url'])) { header("Location: /"); ob_end_flush(); } else { ob_end_flush(); mysql_connect("localhost","<username>","<password>"); mysql_select_db("<dbname>"); $uid=$_POST['uid']; $url=$_POST['url']; $ip=$_SERVER['REMOTE_ADDR']; mysql_query("INSERT INTO user_online (`userid`,`ip`,`url`) VALUES ('".$uid."','".$ip."','".$url."')"); } ?>
Database should have one table called “user_online” which will keep the pings. Create the table using this query:
CREATE TABLE IF NOT EXISTS `user_online` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userid` bigint(20) NOT NULL, `ip` varchar(15) CHARACTER SET latin1 NOT NULL, `url` text NOT NULL, `online_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
Now let’s create a JavaScript code to do the pinging. userid and url will be posted to uop.php in every 300,000ms:
<script type="text/javascript"> function uopPost(){ $.post("http://www.example.com/uop.php",{ 'uid':'123', 'url': document.location.href }, { } ); setTimeout("uopPost()",300000); } uopPost(); </script>
Following page should only be seen by the admins since it will include ip addresses of the users. As before you will need to change highlighted area according to your database name, username and password. JavaScript will update count and user list in every 5,000ms (5s). It also shows users left (timed out) and users joined.
<?php mysql_connect("localhost","<username>","<password>"); mysql_select_db("<dbname>"); if(isset($_GET['rt'])&&isset($_GET['mode'])) { if($_GET['mode']=='count') { $query="SELECT count(distinct userid) FROM user_online WHERE online_date>DATE_SUB(NOW(),INTERVAL 310 SECOND)"; $count=mysql_fetch_row(mysql_query($query)); echo $count[0]; } else if($_GET['mode']=='users') { $query="SELECT users.username,users.userid FROM user_online,users WHERE online_date>DATE_SUB(NOW(),INTERVAL 6 SECOND) AND users.userid=user_online.userid AND user_online.userid NOT IN (SELECT userid FROM user_online WHERE online_date>DATE_SUB(NOW(),INTERVAL 310 SECOND) AND online_date<DATE_SUB(NOW(),INTERVAL 6 SECOND))"; $data=mysql_query($query); $newcount=mysql_num_rows($data); $var = ""; while($info=mysql_fetch_array($data)) { if($var) $var .= ", "; $var .= $info['username']; } if($newcount) echo $var." joined.<br />"; $query="SELECT users.username,users.userid FROM user_online,users WHERE online_date>DATE_SUB(NOW(),INTERVAL 315 SECOND) AND users.userid=user_online.userid AND user_online.userid NOT IN (SELECT userid FROM user_online WHERE online_date>DATE_SUB(NOW(),INTERVAL 310 SECOND))"; $data=mysql_query($query); $newcount=mysql_num_rows($data); $var = ""; while($info=mysql_fetch_array($data)) { if($var) $var .= ", "; $var .= $info['username']; } if($newcount) echo $var." left.<br />"; $query="SELECT newtable.ip,newtable.userid,newtable.url,users.username FROM (users,(SELECT * FROM user_online ORDER BY id DESC) newtable) WHERE newtable.userid=users.userid AND online_date>DATE_SUB(NOW(),INTERVAL 310 SECOND) GROUP BY newtable.userid ORDER BY newtable.url"; $data=mysql_query($query); echo "<table border=\"1\"><caption>Online Users</caption><tr><th>#</th><th>Username</th><th>IP</th><th>URL</th></tr>"; $counter=1; while($info=mysql_fetch_array($data)) { echo "<tr><td>$counter</td><td>".$info['username']."</td><td>".$info['ip']."</td><td><a href=\"".$info['url']."\">".$info['url']."</a></td></tr>"; $counter++; } echo "</table>"; } } else { ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Online Users</title> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript"> setTimeout('update_onlines()',5000); function update_onlines() { $.get('online_users.php',{'rt':1, 'mode':'count'},function(result){ $('#user-online-count').html(result); }); $.get('online_users.php',{'rt':1, 'mode':'users'},function(result){ $('#user-online-list').html(result); }); setTimeout('update_onlines()',5000); } </script> </head> <body> <?php $query="SELECT count(distinct userid) FROM user_online WHERE online_date>DATE_SUB(NOW(),INTERVAL 310 SECOND)"; $count=mysql_fetch_row(mysql_query($query)); $onlinecount=$count[0]; $query="SELECT newtable.ip,newtable.userid,newtable.url,users.username FROM (users,(SELECT * FROM user_online ORDER BY id DESC) newtable) WHERE newtable.userid=users.userid AND online_date>DATE_SUB(NOW(),INTERVAL 310 SECOND) GROUP BY newtable.userid ORDER BY newtable.url"; $counter=1; ?> <div style="height:3px;"></div> Online User Count: <div id="user-online-count" style="font-size:72px"><?php echo $onlinecount ?></div> <div id="user-online-list"> <table border="1"> <caption>Online Users</caption> <tr><th>#</th><th>Username</th><th>IP</th><th>URL</th></tr> <?php $data=mysql_query($query); while($info=mysql_fetch_array($data)) { ?> <tr><td><?php echo $counter ?></td><td><?php echo $info['username'] ?></td><td><?php echo $info['ip'] ?></td><td><a href="<?php echo $info['url'] ?>"><?php echo $info['url'] ?></a></td></tr> <?php $counter++; } ?> </table> </div> <?php } ?> </body> </html>
Here is a preview of what you’re going to see:
Please tell me about the problems you encountered. I will try and help you.
Can you put download .zip ?
I’ve created a gist: https://gist.github.com/oradwell/97a12c14312395ab825defe6c9f540b0
This article is 6 years old and the code is vulnerable to SQL injection. It should ideally be modified to use PDO prepared statements
Can you share download link ?
I’ve created a gist: https://gist.github.com/oradwell/97a12c14312395ab825defe6c9f540b0
This article is 6 years old and the code is vulnerable to SQL injection. It should ideally be modified to use PDO prepared statements