Counting the Number of Online Users Using jQuery Heartbeat (or PHP) - 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.

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

Run php script monthly on windows based server

I need your help to run following php script automatically on 05th day of the every month. Currently I run this manually. Is this possible using schedule task?
Also I don't have admin access to the web server. Therefore cannot use third party automation tools.
PS:
Is it possible to schedule this in a local machine with windows 7 xampp environment and then later update remote db?
session_start();
if($_SESSION['log'] != "log" || $_SESSION['type'] != "***"){
header("Location: ***.php");
}
require_once('conf.php');
date_default_timezone_set('Asia/Kolkata');
$date = date("j"); //get current date
$today = date("d-m-Y");
$now = date("F j, Y, g:i a"); // March 10, 2001, 5:16 pm
if ($date === 5){
//get interest rate
$sql = mysql_query("SELECT Rate FROM Interest WHERE Ref = 'Loan' ORDER BY Date DESC LIMIT 1");
$r = mysql_fetch_assoc($sql);
$rate = $r['Rate'];
//check for not settled loans
$check = mysql_query("SELECT LID FROM Registry WHERE Status = 0");
if (mysql_num_rows($check) > 0){
while ($list = mysql_fetch_assoc($check)) { // while there are rows to be fetched...
//*** Start Transaction ***//
mysql_query("BEGIN");
$loanID = $list['LID'];
//get loan data
$sql = mysql_query("SELECT Registry.Amount, SUM(Account.Total) AS Paid, SUM(Account.Interest) AS intPaid FROM Registry LEFT JOIN Account ON Registry.LID = Account.LID WHERE Registry.Status = 0 AND Account.Auto = 0 AND (Account.LID = '$loanID') GROUP BY Account.LID");
$r = mysql_fetch_assoc($sql);
$amount = $r['Amount']; //loan amount
$paid = $r['Paid']; //sum of paid
$intPaid = $r['intPaid']; //sum of interest paid
//get sum of monthly automatically updated interest
$sql = mysql_query("SELECT SUM(Interest) AS Interest FROM Account WHERE Payment = 0 AND Auto = 1 AND LID = '$loanID'");
$r = mysql_fetch_assoc($sql);
$autoInt = $r['Interest'];
$total = ($amount + $autoInt); //total to be paid
$balance = ($total - $paid); //with no interest
if ($paid >= $balance){
// echo "Loan completed <br/>";
}else{
$int = ($balance * $rate) / 100;
$update = mysql_query("INSERT INTO Account (LID, Date, Interest, Total, Auto) VALUES ('$loanID', NOW(), '$int', '$int', 1)") or die(mysql_error());
if (! $update){
//*** RollBack Transaction ***//
mysql_query("ROLLBACK");
// $_SESSION['error'] = "Interest saving failed.!";
echo "Loan ID: " . $loanID . ", Interest: Rs. " . $int . "/= - Update Failed.!<br>";
}else{
//*** Commit Transaction ***//
mysql_query("COMMIT");
// $_SESSION['error'] = "Interest saved successfully";
echo "Loan ID: " . $loanID . ", Interest: Rs. " . $int . "/= - Update Succeeded.!<br>";
}
}
}
}
}else{
echo "Monthly Interest can be update only by 05th day of the month.!";
}
I dont think at needs admin permissions
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/at.mspx?mfr=true
EDIT:
or even try MySQL Events
http://dev.mysql.com/doc/refman/5.1/en/events.html
It looks all database work which should be easily do able
If it is a publicly accesseable web server, you can use a cronjob service like https://www.cronjobservice.net/. After registration you enter an url and the time they shall call it. I advice using multiple of those services for the case one fails. (your script must execute on first call and exit on subsequent calls from other services.)
Please be sure to properly deal with .htaccess and make sure to have no security relevant output.
Have you asked the peoples that are hosting your site if they have a solution?
Most hosting companies have solutions for this (even on Windows servers)
If the hosting company has no solution for this (what I seriously doubt) you can call the script externally from another server that has cron possibilities or have it called by the first visitor on that day.
I any case you will want to include a check in your script that your script only runs on the set date (you already have that) and also make sure that calling the script more than once on that day is no problem.
PS : if the script is called by the first visitor you will have to consider the fact that you could not have any visitor that particular day, so the script will have to run whenever the next visitor comes along.
If you don't have administrative access to Windows, you won't be able to create a scheduled task. Your only alternative is to create some sort of custom task component in your application that checks / stores the last time a script was run. The problem with this is that it relies on user activity and it may not run on the exact date that you want it to.
The other alternative is to find Linux hosting so that you can avail of Cron.

Accurately count active users? (PHP + MySQL)

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.

Get records from a table with timestamps / echo a message in the row when the timestamp difference is more than 5 minutes

I get a list of records and each record is a question / answer / timestamp.
I created a basic PHP report:
<?php
$con = mysql_connect("localhost", "login", "pass");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("db", $con);
$result = mysql_query(" SELECT *
FROM `experiment`
where userid = 73");
while ($row = mysql_fetch_array($result)) {
echo "question " . $row['question'] . "answer " . $row['answer'] .
"time " . $row['time'] . "stamp " . $row['createdAt'] . "<br>";
}
I need some way to compare the row in front of createdAt and the row after createdAt.
If the difference between two rows is bigger then 2 minutes, the thing should echo "warning".
I'll assume a couple of things on your behalf. This may change the value of the answer, but you simply haven't provided the necessary information for an answer to be feasible at this point.
I am going to assume that you are looping through the data records. You imply this by stating that there is a display of multiple rows. Your SQL query only gets the data of one row. I'll assume that you actually have gotten an entire record set instead. Because otherwise, the data structure needs to be examined for its design choices. I am also making an assumption on how userid is used in a table, mind, so that's my personal bias.
As record sets are collected, they can be manipulated. You're using the ancient mysql_* method here. I recommend that you read the PDO methodology that php has available at 5.2.7+ and consider upgrading your php version if you don't already have it.
The manipulation can take many forms.
$previousRecord = 0;
foreach ($recordSet as $index=>$record){
$recordSet[$index]['warningTime'] = FALSE;
if ($previousRecord){
if (($record['createdAt']-$previousRecord) > 120){
$recordSet[$index]['warningTime'] = TRUE;
}
}
$previousRecord = $record['createdAt'];
// Other data manipulation logic for page presentation
}
This should inject the warning right into the dataset that can be displayed whenever you want it to be. I do prefer a seperation of functions for maintainability; calling the database, extracting/formatting the data, displaying the data. It makes future changes much easier, also allows for code portability. You do not have this in your code, which means that whenever you do something like this again, well, you'll re-invent the wheel.
$createdAt = null;
while($row = mysql_fetch_array($result)) :
// initialise on first run
if ($createdAt === null) :
$createdAt = $row['createdAt'];
endif;
// now $createdAt is the value of the last row... if so, echo warning, else echo nothing
echo checkCreatedIsOlderThanTwoMinutes($createdAt, $row['createdAt']) === true ? "WARNING!" : "";
echo "question ". $row['question']. "answer ". $row['answer']. "time ".$row['time']."stamp ". $row['createdAt']."<br>";
endwhile;
I don't have a clue what the format of your createdAt looks like, so I use this pseudo-function:
function checkCreatedIsOlderThanTwoMinutes($oldCreatedAt, $newCreatedAd)
{
// check that stuff
}
Hope that helps.

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