Accurately count active users? (PHP + MySQL) - php

Basically, I've been trying to get an accurate measure of how many active users my site has. I'm tracking sessions on the DB, and also doing some clean-up based on the USER_AGENT to remove bots/spiders/crawlers (very basic stuff though).
What I get is a very high number of sessions, even after removing duplicate sessions for the same IP. In fact the number of sessions is 10x larger than what Google Analytics and other User Tracking systems report, so there's gotta be something I'm doing wrong.
Here's part of the code where I keep track of sessions:
//Start session if not active already
if(!isset($_SESSION)){
session_start();
}
//Determine whether bot or browser
$bots = array(
'bot',
'crawler',
'yahoo',
'spider',
'google',
'$^'
);
$ua = $_SERVER['HTTP_USER_AGENT'];
$uam = preg_match('/'.implode('|', $bots).'/i', $ua);
$uatype = ($uam)?'bot':'browser';
//Add session to DB if new or expired
if ($_SESSION['renew'] < time() || !isset($_SESSION['renew'])) {
$_SESSION['renew'] = time() + 900; //15 minutes
$sql = "INSERT INTO " . SESSIONS . " (session_id, user_id,
renew, user_ip, type, useragent) VALUES ('" . session_id() . "',
'" . $myuser->get('user_id') . "', " . $_SESSION['renew'] . ",
'" . $myuser->get('ip') . "', '$uatype', '$ua')
ON DUPLICATE KEY
UPDATE renew = " . $_SESSION['renew'] . ",
user_id = '" . $myuser->get('user_id') . "'";
$site_db->query($sql);
$sql = 'DELETE FROM ' . SESSIONS . '
WHERE renew < ' . time();
$site_db->query($sql);
}
So, I'm storing the session info in DB and then renewing / expiring every 15 minutes as necessary.
If I then query the DB for sessions that are from browsers, with unique IP addresses, I get about 10x as many as JS systems are reporting.
Even if I try to reduce the number by only counting entries that have their first two octets of the IP address unique, I'm still way over.
Any tips on what I could be doing wrong on my session tracking?
The query to get the counts goes like this:
$sql = "SELECT count(DISTINCT(user_ip) FROM ".SESSIONS." WHERE type = 'browser'";
As a note, the bot trap is already discarding about 66% of the sessions. If I didn't do that, I would get close to 40x as many "active users" as GA reports.
Thanks.

Maybe storing those records and then do a query like this:
$sql = 'SELECT COUNT(*) FROM ' . SESSIONS . ' WHERE renew BETWEEN ' . $expire-900. ' AND ' .$expire;
And for performance reasons, let a cronjob do your deleting.
For example: Delete every record that expired an hour ago. And do that every half hour or something.

Related

how can I define how long a client was visiting a site

I have a site and I want to measure how long a client was connected to my site, one hour or two hour... or? how is it possible?
can someone help me in this regard.
it will be appreciated.
As mentioned in the comments, it's best to use analytic software but if you are looking for something simple (or just learning experience)
<?php
session_start();
if(!isset($_SESSION['sessionId'])) // No session, first time (subject to session timeout)
{
mysqli_query("INSERT INTO visitor_sessions(`started_on`, `last_checkin`) (" . time() . ", " . time() .")");
$_SESSION['sessionId'] = mysqli_insert_id(); // start the 'visiting session'
}
else
{
mysqli_query("UPDATE visitor set `last_checkin` = " . time() . " WHERE id = " .$_SESSION['sessionId']); // Update last checkin
}
?>
visitor_sessions is a table with 3 columns, id, started_on and last_checkin (timestamps).
You can include this script in your pages thus updating last check_in with each new page opened or have jquery call it every x seconds to maintain time even if they just view a page.
PS: Code was not tested but this is the general idea

Fetch from database not working?

So I have the code below (and at the top the database connector and session start). However, he doesn't echo the amount of cubes (a valuta on my site).
$cubes = mysql_query("SELECT cubes FROM leden WHERE id='" . $_SESSION['id'] . "'");
echo "You currently have " . $cubes;
What is going wrong here? The database is there, the tables and everything exist.
The mysql_query function returns you a result set. So if you want to get the information you must also do :
$cubesRow = mysql_fetch_object($cubes);
echo "You currently have " . $cubesRow->cubes;

Counting hits and adding to db but after a while site starts running slow

I'm faced with this issue only on high volume traffic sites.
Here is the problem and this is wordpress related as well.
I'm counting page hits using an ajax function that gathers a couple details about the page and adds the info to a separate database on the same server.
Everything works fine for a while then the site starts to load slow and at times will say, Can't Connect to Database and the site stops loading for a few seconds or so.
This problem happens mainly I'm guessing because of the massive amount of traffic hitting all the pages on site (over 30-50k a day) and after a while the site is having trouble keeping up with the ajax function requests and or writing to the other database.
Question is, how can I get this to count on large scale traffic sites and not keep getting a slow or crashing database. BTW. Site is on a dedicated server and the wordpress site does have a caching plugin installed.
if ($user_role != 'author' && $user_role != 'administrator' && $user_role != 'uploader' && $user_role != 'editor' && $user_role != 'contributor') {
$insert = "INSERT IGNORE INTO " . $pps_new_table_name . "( post_id, post_author, create_date, hit_count, {$browser_column}, {$device_column} ) VALUES (" . $_POST['post_id'] . ",'" . $_POST['post_author'] . "','" . $create_date . "','1','1','1')
ON DUPLICATE KEY UPDATE hit_count=hit_count + 1, {$browser_column}= {$browser_column} + 1, {$device_column}= {$device_column} + 1
";
$results = $wpdb->query($wpdb->prepare($insert));
$wpdb->show_errors();
}
die();

Counting the Number of Online Users Using jQuery Heartbeat (or PHP)

I am currently using this php code to count the number of the users currently online:
$session_id = session_id();
$time_stamp = time();
$time_limit = $time_stamp - 300; // We give the session only 5 minutes if it exists
$result = $this->select("SELECT * FROM `online_visitors` WHERE `session_id`='$session_id' LIMIT 1");
if (!mysql_num_rows($result)) {
$tb_col[0] = "visitor_ip";
$tb_col[1] = "country";
$tb_col[2] = "session_id";
$tb_col[3] = "time_stamp";
$tb_col[4] = "last_time_stamp";
$tb_data[0] = "'" . $this->visitor_ip . "'";
$tb_data[1] = "'" . $this->visitor_country . "'";
$tb_data[2] = "'" . $session_id . "'";
$tb_data[3] = "'" . $time_stamp . "'";
$tb_data[4] = "'" . $time_stamp . "'";
$this->insert("`online_visitors`", $tb_col, $tb_data);
} else {
$this->update("`online_visitors`", "`visitor_ip`='$this->visitor_ip', `country`='$this->visitor_country', `last_time_stamp`='$time_stamp'", "`session_id`='$session_id'");
}
$this->delete("`online_visitors`", "`last_time_stamp`<'$time_limit'");
But it does not update in real time. I want to check the number of users every 30 seconds. I may also want to connect this table to the jQuery heartbeat function, so I know more reliably how many users are currently online.
Am I approaching this properly? Any tips for how to achieve this in jQuery (I'm not very good with it)? Or can my approach be improved?
I also want to improve my php code
You can also do this the other way around: instead of updating the time via ajax, you assume that the user is online until he leaves the page or closes the browser. In this case you use ajax to set the user as offline and execute it when browser fires onbeforeunload. In rare cases (power outage, system crash) this event will not be fired, so its a good idea to check also when the last update was made in case you have a floating user.

Show Number of Live Page Viewers [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to count the site current visitors using java script or php
I have an embedded stream on my website, but I want to pull the number of live viewers on the page. Is there a way to do this with PHP / AJAX, show the number of people currently viewing one of my webpages?
DISCLAIMER: I did something like this a LONG time ago, so here is the ugly old code (That I'm not going to put effort into making look nicer / not when I first started programming as this is just to give you an idea of how it can be done, and not to spoon feed any specific code).
$timeout = time() - (20);
$sessid_exist = mysql_query("SELECT sessid FROM bw_sessions WHERE sessid='" . session_id() . "'") or die (mysql_error());
$sessid_check = mysql_num_rows($sessid_exist);
if ($_SESSION['bw_username']) {
$sql = mysql_query("UPDATE bw_sessions SET timestamp='" . time() . "', username='" . $_SESSION['bw_username'] . "' WHERE sessid='" . session_id() . "'");
} else {
if($sessid_check > 0){
$sql = mysql_query("UPDATE bw_sessions SET timestamp='" . time() . "' WHERE sessid='" . session_id() . "'");
} else {
$sql = mysql_query("INSERT INTO bw_sessions (id, username, sessid, timestamp, ip)
VALUES(null, '', '" . session_id() . "', '" . time() . "', '" . $_SERVER['REMOTE_ADDR'] . "')") or die (mysql_error());
}
}
$sql = mysql_query("SELECT distinct sessid FROM bw_sessions WHERE username='' AND timestamp >= '$timeout' ORDER BY timestamp DESC") or die (mysql_error());
$sql2 = mysql_query("SELECT distinct sessid,username FROM bw_sessions WHERE username!='' AND timestamp >= '$timeout' ORDER BY username DESC") or die (mysql_error());
$num_guests = mysql_num_rows($sql);
$num_reg = mysql_num_rows($sql2);
?>
<font size='1'>Currently Online: <br>
<?=$num_guests;?> Guests<br>
<?=$num_reg;?> Registered users
You just need to make a table and hold session_id's.. then query that table for any "recent" activity. If you want real time updates, put code above (modified to your table design) in "online.php" and call it via jquery every x seconds, or however you decide to do it.
Something like Clicky should work for you.
If you've seen it somewhere, it probably IS possible, and this sort of thing is built into most forum sofware, and it's used on a lot of websites, so it's probably not that hard.
The usual way of doing this gets the IP of a connected visitor from $_SERVER['REMOTE_ADDR'] and then writes that to a file, and adding up all the unique IP's to find out how many people are connected.
This will need some sort of cleaning function to remove any IP's that are no longer connected.
The script runs on pageload, and counts visitors in a file, so if using ajax you run a PHP script polling that file every so often to update the count dynamically, or you could do it on pageload, but then ajax is'nt necessary as you could just do it with PHP.
If you don't already know how, figuring out how to run a PHP script in $.ajax is the first thing to do, then writing a function that counts visitors is probably the next.
I got 244 million hits on a search for such a script, and there's one here and here.

Categories