Take the 2-minute tour ×

I have log table for all users of website

enter image description here

I'm recording various data about user righ after successfull login.

If signout_dt field not filled and status is 1 for some user_id, website prevents login automatically.

For that who have cookies - there is no problem.

The problem is,lets say user signed in without cookies: only sessions variables. I have no idea, how can I update db table and signout user let's say after 30 minute inactivity. Note that I can't create cron job or something serverside, because using shared hosting.

Heard that, it's possible to create some script like heartbeat that continously sends some data about user activity. But I think this will heavily load the server especially if there are more than 1000 users.. Any suggestion, tutorial, article, something else?


Deceze tried to explain but I really need better explanation (better idea), with code.

share|improve this question
Is the problem that you prevent login because of data in your database for a user? –  hakre Feb 28 '12 at 16:04
@hakre Yeah. My php side regenerates session in every user activity. I can solve problem just by decreasing session time to 30 minutes: after 30 minute inactivity of user session will be expired and my protection script will not allow user to enter secure zone of web site. But problem is, how to detect that, session of some user expired and "close" (I mean add signout_dt ...) the row for this user in mysql db table? How can i do that without using any cron job? –  heron Feb 28 '12 at 17:55
Use onbeforeunload function to send user's id via Ajax to PHP and update db table with sent id. –  Tural Aliyev Mar 1 '12 at 7:29
Got this work with that func. Thx for key function –  heron Mar 1 '12 at 7:31
@epic Just don't expect this to actually work reliably. There are a thousand different scenarios where that function will not fire and the user will not be logged out. You have to deal with this situation as well. –  deceze Mar 1 '12 at 8:17

3 Answers 3

To "timeout" a user, simply note the time he was last seen. Then, when necessary, check if the last time you've seen the user was over x minutes/hours/days, and consider the last session timed out. You don't need to run a cron job or anything that cleans up after users in realtime, you only need to be able to determine if some information should be considered stale when you need that information.

You may want to occasionally run a cron job or something to clean out old, unnecessary data, but that doesn't need to happen in realtime. You could even run this as part of a regular page request:

if (mt_rand(1, 1000) == 1) {
    mysql_query('DELETE FROM `table` WHERE `last_seen` < some point in time');

To note the last seen time, just run this query on each page load:

UPDATE `table` SET `last_seen` = NOW() WHERE `user_id` = ...

To avoid thrashing the database with these queries, you can also just do it every so often. Keep a "last_seen_last_updated" timestamp in the user's session, then on each page load check if you might want to update the database:

if ($_SESSION['last_seen_last_updated'] < strtotime('-5 minutes')) {
    $_SESSION['last_seen_last_updated'] = time();

That gives you 5 minutes of jitter, but that's usually perfectly acceptable.

share|improve this answer
This much I know too. The problem lets say, user closed browser window, all session variables gone, But db side still "thinks" that user online-because user didn't pressed sign-out button. Can't figure out solution for this problem.. –  heron Feb 9 '12 at 7:50
@epic You can never depend on the user signing out, therefore you use a strategy as described above. Sessions don't need to be closed, they can simply be considered stale and timed-out after a certain period of inactivity. That's the only thing you can really do in a stateless, connection-less environment like the web. Your premise of requiring a session to be marked active or inactive is flawed. –  deceze Feb 9 '12 at 7:53
Maybe I'm misunderstanding you but when user closes browser windiow all sessions vars will be auto erased. But in db table will not be any change, because nothing fired update function. When user will reopen browser, website will require login credentials (because there is no session var), but there is one problem, in db user still online. How about this? Website of-course will prevent login –  heron Feb 9 '12 at 8:02
@epic I don't really understand your session management system. Why do you block users from signing in on two machines at once? That's rather uncommon and is not typical for how a web app works. And the session information on the server is not destroyed when the user closes the browser. The browser only discards the cookie that holds the key to the session, but the session data is still active on the server. It is being cleaned out with the same logic as described above. –  deceze Feb 9 '12 at 8:15
@epic With the system you describe, where you apparently require a user to sign out before he can sign in again, you will always have the problem that the user won't be able to sign in again unless he has logged out before. That's the nature of stateless, connection-less sessions. If they aren't ended explicitly, they can only end through a timeout. –  deceze Feb 9 '12 at 8:18

Your management of sessions is broken and does not conform to accepted stateless behaviour - in as much as you apparently require the user to sign out, which rarely is the case in web applications -- most people just closes the browser, and the cookies will just float around and appear next time the user accesses the website. If the system wants the user to sign in again, then the web server will have to validate the session -- for example using a timestamp and/or cookie signing etc, and invalidate the cookie to force the user to re-login if needed.

Hence you should treat cookies and sessions variables the same -- that is; have your server side generate a unique signed value. Keep an expiration time (for example now()+20min) either in the cookie/session variable or keep the expiration time in the database.

At each access check that the cookie/session-variable is correctly signed, and check that it is not beyond the expiration time, and update the expiration time to allow another 20min.

If the access is past the expiration time -- i.e. the user has been idle for too long, then clear the cookie/session-variable and force the user to login again.

If you keep the expiration time in the database, you simply write a small program which once and day or once an hour run though all records and remove those which you deem too old.

share|improve this answer

As per my understanding of your question, you want to address following things:

a. If for a given period of time, a user is inactive then he should be logged out and your database table gets updated. Here being inactive means, user has not used keyboard/mouse for a given period of time.

b. If a user closes the browser without logging out, then he should be forcefully logged out and database table gets updated.

Both these things can be accomplished using Javascript Functions and Ajax. Following is the flow which we have in our application for addressing above issues:

  1. Create a Javascript function, say logoutUser(), which will send an Ajax request for updating the database tables and destroying the session.

  2. Use Javascript function - setTimeOut - to call logoutUser() function after time period you have set for inactivity.

  3. Use Javascript events to catch mouse movement and keyboard activity and in every such event call use successively clearTimeOut (in order to remove the old time for execution of logoutUser()) and setTimeOut (for setting the new time of execution of logoutUser()). This way you would be able to catch the inactivity and logout the user after a period of time.

  4. For taking care of the issue related to closing of browser window use 'onbeforeunload' event of javascript and in this event send the Ajax request for updating the database tables.

As our application uses ExtJS, thus, we have used ExtJs library functions to detect events. You can also prefer using some Javascript library for catching the events and implemeting the above solution.

Hope this helps.

share|improve this answer

Your Answer


