Tracking how many hours users spend on my website - php

I am writing a usersystem and as a statistic available for all my users I want to be able to provide them with the amount of hours they've been active on my website.
my original idea as to how to do this was:
user loads a page, and a record for the user is stored in a SQL table called accessLog
*user loads another page, sql query runs to see when they last visited a page*
if the user visited a page within the past two minutes, update their user account and add the time spent online
*insert a new record into accessLog*
however this would mean adding a potential of 4 additional queries to every single page of my website, which seems slow. I was thinking, there has got to be a more efficient way of tracking user activity online that I'm clearly too stupid to see!

My way of doing this is simple:
When a user loads a page, their "last page load time" is updated in the database.
A cron script runs every minute. It looks for users whose "last page load time" was in the last minute.
Increment the "time spent on site" for each user found.
In this way, I can keep track of users accurately to the minute. Just divide by 60 to get the hours.

I would use ajax to get the clients to call the server ever minute or so. Just a to tell the server that the user is still watching that page.
The server would have a lastTimestamp and a totalTimeSpentOnSite in a database. The lastTimestamp would simply have the last time a ajax request or page load occurred.
Every time the ajax fires the server would calculate now - lastTimestamp and add that to the totalTimeSpentOnSite.
To make it even more accurate you could
add javascript listeners to onBlur() to record only the actual time spent with that window active and then send that time to the server instead of just telling the server that the user is still active.

My philosophy is this: don't be overly concerned with efficiency until it becomes a problem. Unless your site has really heavy traffic, you won't notice the four queries. This might be simpler, though:
Log every page load.
Every few hours, run a script through cron that calculates time
spent online for each user and updates a running total in the user
table.
Periodically clear out your access_log table.

Add it to your session management. When a user starts their session record their start time. When the user ends their session record their end time. Simple math from there will gather you the total amount of time they are spending per session on your site.
To answer Filip Haglund
yeah but you'll have to wait for the session to time out, and that time doesn't reflect the actual time the user spent on the last page before he/she closed it.
That's true but then again, all of the answers available so far work on the same basic premise:
Log the page load time.
Log when the user leaves
Update a database table
It just so happens that to log when the user leaves you need sessions. I don't know of any other way in PHP to keep track of user activities the way OP wants. Updating the database table is a technical matter. Do you wanna use a CRON job? Do you wanna use AJAX? Do you wanna do something else?
If you really wanted to know how much activity was actually occurring you could send off AJAX requests for certain JavaScript events. This will tie the time tracking to actual browser events. Of course this means your time tracking relies on JavaScript being enabled.

The "two minute" rule is a little unreliable - and you can get tied up trying to work out what "time spent" actually means.
In a previous project, we did the following.
On each page load, we checked if the user had a current session, and if not, created a GUID to identify the current session.
We wrote a log record to the database with the datetime, GUID, page URL, and user ID (if the user had logged in).
To calculate "time spent", we calculated the time difference between the first and last record for the session GUID, and added one minute to reflect the time spent on the last page.
This is not entirely accurate, but it can run realtime without the need for CRON for sites with moderate amounts of traffic.

first choose a duration beyond which a session is considered interrupted. (ex: 10 minutes)
log all page load with all ip in database
if time between 2 page load for one ip is more than duration don't add this time to the total time for this ip
if time between 2 page load for one ip is less than duration add this time to the total time for this ip
2 problem is :
- if user stay more than duration (10 minutes) in a page without refresh he's considered as disconnected.
- the last page duration is not saved
Piwik works like that

This is what i use and it checks updates the DB anytime the user loads any page.
The data is accurate, as it calculates if the user loads a page per minutes, if so, it adds the time difference to the DB.
$now= time();
$stmt = $db_con->prepare(" SELECT last_seen,time_online FROM user_online_log WHERE user_id=? limit ? ");
$stmt->execute(array( $user_id, 1));
$fetch= $stmt->fetch(PDO::FETCH_ASSOC);
$last_seen=$fetch['last_seen']; //integer value from db, saved from time() function
$last_seen_plus_one_min= $last_seen + 60;
if( $now < $last_seen_plus_one_min ){
$additional_time_online= $now - $last_seen; }
else{ $additional_time_online = 0; }
//update db
$stmt12 = $db_con->prepare(" update user_online_log set last_seen=?, time_online = time_online+? WHERE user_id=? limit 1 ");
$stmt12->execute(array($now, $additional_time_online, $user_id));

Related

Browser game PHP+MySQL increasing resource every second

I'm create a small browser game and I'm programming the resource handler.
I'm using PHP and MySQL database.
I realised that I can't update the database every second to increase my resources, so reading on Stackoverflow, I found this post:
I am also trying to make a online game in PHP and encounter also this
problem. My solution was actualy pretty simple. In Assuming you are
using different city's or planets, you will need a database table for
the city/planet. In this database you store the current resources and
the resources per hour. And also a timestamp.
For upgrading resources facility (gold mine for example) i have a
database that has all the building ques with a begin time and end
time.
i then have made a page that i include on every page in the game. It
first checks if there
are any building ques for the selected city that
should be finished since last time database was entered. If that gold
mine was finished at let say 12.00 and the timestamp on your city was
11.00 and current time is 13.00. What the page does, it calculates all the resources for the time 11.00 to 12.00. Then it will update the
gold per hour in the city table. And then it recalculates the
resources from 12.00 to 13.00.
when all the above is done, it puts the timestamp on current. But as
you have all the resources per hour from the second run, you can store
it in an array and let a local timer run to update the resources on
screen. But since you include the above mentioned page on every page,
when you go to the next page it will acces the database to see what
the current resources should be. So the local data is only for
viewing.
By DutchEcho
This is the link: LINK
I programmed the events queue and everything is fine. The problem, now, is to increase the resource if the player is online.
If I save the last_login of the player by time() and then I calculate the new amount of production I have a problem:
"UPDATE `stats` SET `rock` = `rock`+(('".time()."' - $last_login)*$rock_production)
I do: time() - $last_login. If I save the last_login every time a player reloads or changes page, this difference will be always 0.
Because the two times are equal.
How can I increase my resource every second?
Rather than updating last_login on each page load, only update when you start a session. You might have a second field that you update on each page load, and use the difference for your calculation. The two fields could also be used to indicate the duration of the most recent "time on line" even after the user disconnects.
[edit]:
How about using an update trigger? In a single statement you would have both values of last_login available - the new value and the original value.

Update information at specific timestamp

I'll try to explain my question the best way I can.
I'm not asking for codes, only for the best method of doing it.
I want to create a browser game and use time for upgrading stuff, building etc.
For example, to build 1 house will take 1 hour.
So I will began with saving the timestamp+(60*60) at the moment the user did his action.
My question is, how to update it the best way?
One way I thought of was to add function that check every page view of the user if it's done.
But then if he's not logged in the update wont happen.
Second way i thought about is for every page view of any user to check for every user registered. But it's not effective and there is a problem if no user is logged in.
Any suggestions?
I had my game doing it simply, without crons.
When a player wanted something that takes time, i just updated his database information with the appropriate time of ending that job (columns are just examples)
UPDATE player SET jobend = UNIX_TIMESTAMP() + (60*60*4) # ending in 4 hours
Then, every page that had an information about the remaining time, i just used something like this:
SELECT (jobend - UNIX_TIMESTAMP()) AS jobremaining FROM player
I formatted correctly the time using strftime and i displayed that to the user.
In the case the remaining time was negative, the job was done.
There was no-need for absolute counting since user was able to do something with the job when he was connected.
When the player just changed pages or doing something else i had a function where i just checked all timely events while the user was online (so to catch any negative timer), then presented with javascript any change (i posted javascript counters for every page)
Now, if you talk about updating in real-time, cron is the way but are you sure you're going to need it for a game? I asked that question myself too and the answer was not.
EDIT
If another player sees the buildings on schedule page (an hypothetical page) i am doing the same calculations; if a time just got negative for a specific player (regardless if another player see the page), i just reward him with the building (in database i make all the changes), even if he's offline. There's no harm in this, since he can't do anything anyway. The other players will just see he has a building. The key here is that i execute the required updating PHP code regardless of player's connection to the game; as long at least ONE player is logged-in i'm executing the progress function for everything.
This isn't so slow as it sounds (updating all players by using just a connected player that visits a specific page). You just have a table of 'jobs' and check timers against the current time. More like a single query of getting the negative ones.

Total time registered user have been online

I am right now programming a community in PHP, but i'm stuck, as i can't figure out, how to see how long my users have spent on the site. It should be showed on their profile, such as: "This user has spent 10 hours and 10 minutes on sitename". But i have no idea, how i should make this!
I think of adding a row to my users table (In my MySQL database) called 'last_visit_time' to store the time the user last time visited a site on my website and one called 'total_time' to store total time spent online.
Then everytime a user loads a page, it first check if you'r logged in. Then if you are, it first checks if('last_visit_time' + 2 minutes >= $current_time) then, if that is true, it add the difference of 'last_visit_time' and $current_time to the 'total_time' row. After that, it updates the 'last_visit_time' to the currently time.
This will give a 2 minutes tolerence, for users to visit a new page - and then it add the time spent on the previous page (If it's under 2 minutes). As what i can figure out, there is no way the users can cheat with this script, because you will be gained nothing by spam-updating the pages or visiting the page in 2 windows (On same account).
But how can you actually get the difference between currently time, and last_visit_time, and check if there has passed more than 2 minutes! Or should i make this a different way?
I'm quite open for suggestions and especially help, as it is needed very much.
Thank you!
I have solved this with easy script. I have time "tollerance" of X minutes. Every time, user open another page, before page is "rendered" I run script "update user time". I have stored last time of user activity, now take current time and make difference, which gives me time since last "update". This time I add to user time spend on my site.
For measuring time, I use simple UNIX time stamp, which is easy to deal with. Just substract two numbers and get time in seconds since last activity.
Hovewer, it has one drawback.If user goes somewhere else. He can be hours on single page and then go out. This will never be counted this way. For this to also count, you will have to use JavaScript and timer, that will launch script via AJAX every now and then and do the same as if user "click" on another page on your web.

Generate a list of online users?

I'm not awesome enough to write a chat application, and I'm trying to get one to work, and I've recently downloaded one from here, it's pretty good so far, as I've tested it out on XAMPP, but I have a slight problem. I'm trying to generate a list of online users to give it a more practical application-like feel, but the problem with that, is I have no clue how to do it easily.
When users login to my site, a session named g_username is created, (the chat says 'username', but I'll fix that) and from what I see so far, the easiest method would be to store their username in a database called OnlineUsers and call that data via Ajax, but, the other problem, is that it's session based, and sometimes the users can just leave, without logging out, and I intended to run a script to logout the user from both the OnlineUsers table, and by deleting the session.
If they leave without logging out, they'd be online forever! I could potentially suffix a bit of code on every page, that toggled an ajax event on page close, the event being a script that kills their OnlineUsers table record, but then again, that would load the server with useless queries as users jump between pages, as far as I'm aware.
Creating my entire site in Ajax isn't really an option, as it's a load of different sites combined in to 1 'place' with a social 'layer' (if you will) from a social service.
Does anyone see a way to do this that would make sense, and be easy to integrate, and do with Apache, without command line access?
You could so something like storing a timestamp of the users last action in a database, comparing that timestamp when outputting online users and making sure that it was done at most 1 min ago.
Run on all/vital pages:
(Deciding if the last action is outdated, you could also check if it was done for one minute ago to reduce the database-load)
if($user['lastAction'] < time()) {
//update into database, last action is outdated
}
When calculating the amount of users online and is within the loop of each timestamp
//If the users last action was within a minute, the user is most likely online
if(($row['lastAction']- time()) > 60*60)
//count user as online
you could have a cron job [if you have cpanel] running on the server once every 60secs or so, that checks when a user last sent anything via the chat if they have not in the last lets say 5mins then remove their entry from the online users list.

How to handle user online status when he/she close the browser?

I am having table to track user online status by setting 'is_online' field to 1. Now User get logged in the site and shut down his/her system or power down at that time he/she logged in.
Here in database 'is_login' has the value '1' which means he is still using the site.
So I have to do some logic to change that value to '0'.
How can i handle this situation using PHP ?
The normal solution is to store a timestamp in the table which you update every time the user does something. Users with a recent timestamp (say, five minutes) are shown as logged in, everybody else are logged out.
It doesn't even have to be updated on every page load. Keep a timestamp in the session with the last update time as well, and only update the table when the database flag are about to expire.
Store an time-since-last-activity. When it's been longer then a specified time - treat as if offline. You should replace the is_online with an DateTime field, and update it every time the logged in user visits the website.
On the place you want to select all online users, instead of :
SELECT * FROM users WHERE is_online = 1
You could use:
SELECT * FROM users WHERE is_online >= DATE_SUB(NOW(), INTERVAL 5 MINUTE)
you can't. HTTP closes the connection once the page has been delivered. On the server side alone all you could do is checking if a user has requested a page within a certain amount of time.
JavaScript might be your friend. You could use it to create a ping to a php script which then updates the last request timestamp. Once there is no more pinging, the user is gone and you'd know.
If you have trouble with javaScript, a good point to start would be here: http://www.w3schools.com/JS/
You might want to focus on the AJAX and HTTP request stuff.
cu
Roman
You can use jquery to update your site each X time, so a function is executed each 10 seconds, as following code:
function updateTheBBDD(){
... calling mysql_connect -> mysql_insert -> mysql_close
}
setInterval("updateTheBBDD()",10000);
Also, when painting the user status monitor instead of consulting the BD and:
1->green
0->red
You should:
actual - time > 10 ---> red
actual - time <= 10 ---> green
Due to the stateless nature of the web it is not possible to know exactly when the user left your website. So you can't really trigger any code to change the mentioned value.
As the other have said one has to store the time-since-last-activity to get an approximate idea when was the last time the user was actually doing something with the website.
HTH :)

Categories