I'd like to induce a function after the session is destroyed (i.e. user closes the browser). This function would change a value in my database from true to false. Is that possible?
I would suggest you to register the user last activity in your database, this way it's 100% accurate.
Then by comparing the registered date with the current time, you can decide when the user is active or not.
If you really want to know if the user is still on your page, you could also do something, but you should avoid it :
On the client side, make a javascript loop, for example each minute, that tell to your server the client is still there. When the client will close his page, the loop won't make any new query.
I'm guessing that you're wanting to figure out whether a user is online or not (or something similar?) The only way to "know" (read: guess) that a session is dead is to store the time that the user was last active and then compare that time against the current time. Then, depending on your needs, you can decide to make the assumption that a user who has been inactive for 30 minutes is offline.
Only way to do this is using Javascript to detect a close and using a Ajax request (using XMLHttpRequest for example) to your PHP page (which handles the logout part).
See Browser/tab close detection using javascript (or any other language) for more information on the closing part.
Related
I have developed a website in which server side coding is done through PHP and I am using MySQL database. There is a specific page on my site that should be opened only once at a time, that is, if it is opened by one person at the same time, the second person should get a message "This page is opened by someone, you can't use it at this time" I thought of a logic that I store timestamp in the database and compare the time from the database and if it's same as that time then it means the page is opened by the other person so access should be restricted. But I don't find this logic reliable. Could there be any other logic that could be implemented?
Obviously this is quite an open question and impossible to give a complete solution to without actually seeing your database/code.
However, here would be a pretty stable logic:
User attempts to access current page.
1) PHP checks DB if session_on_page is not Y.
1a) If Y: Error Message, page in use.
1b) If not Y allow user to access and set session_on_page_user to the users login id or username etc.
2) On page load, start AJAX session that re-logs Y every 5 seconds along with current username.
2.1) Using JavaScript, check for onunload and run a AJAX function that sets session_on_page to N and also wipes session_on_page_user.
That process will be fine if it's simply for viewing data. If there's also any forms/edits being made whilst on the page I would suggest hashing the current time along with user name to create a fairly secure hashkey that is unique to that user and compare it against server time when performing any updates. You may want to go even more secure than this depending on your case scenario. You could use PHP sessions to double check also and potentially even some Apache handling.
Like I said, it's quite a broad question so we can only really give suggestions to logic.
I'm doing research on internet behavior. The participants of my study are asked to fill in a questionnaire.
What they don't know is that this questionnaire consists of an infinite series of forms:
whenever they submit one form, they are presented with another one. From their perspective, the questionnaire never ends. It is filled from an array containing thousands of random questions from old studies.
I want to test, how long different users keep going.
I have two options:
Save each form to the database, when it is submitted. Each successive form UPDATEs the same data record with the current page count. This is easy, and I know how to do it.
No data is saved while the user performs the task. The current page count is saved from the SESSION, when the user abandons the task, i.e. when he closes the browser window.
How do I do this? How can I tell PHP to save a $_SESSION variable, when the user closes the browser? Is this even possible in a reliable way, i.e. the solution does not rely on functionality that is not available in all browsers, such as onbeforeunload (which does not work in Opera)?
$_SESSION is profoundly unfit for the task you want to perform. It is designed (and works well enough) as a vehicle to introduce state into an application relying on the stateless HTTP protocol, not to do something on the absence of further HTTP requests.
When relying on a server-sided mechanism, one of the main points to consider is, that session cleanup can happen concurrently, which is not a problem for dumb destruction of a session, but will hand you problems if you want to do something else.
Relying on client-sided code is much worse: What if the user doesn't close the browser, but it crashes? Or the user is on mobile and drives into a tunnel?
My recommendation would be, to understand, that your problem at hand is not one of session keeping, but one of analytics. This would argue heavily into inserting one row per page into a database:
Do your analytics a posteriori: Are you sure, you already know all questions, you want to ask? Only raw data is able to allow you to change or append to your research problem.
Including a timestamp in the rows will allow you to ask for correlation between response time and total time ... was the user doing your survey just as a side-distraction or was he concentrated on it?
Basically you create a specialized log, that can be analyzed by lots of tools - it being in the DB making it easier to query it.
What I do now is save the current state of the session into a database with session_encode() after each form is sent. Before I show any user any page, I check if there is a session with isset($_SESSION['whatever']). If there is none, I check in the database, if a session was stored for this user (they are identified through a login, all this takes place on a site that requires registration). If a session was stored, I drag it from the database and resore it with session_decode(). If there is none, I create a new one. Now, when the browser was closed, the user gets returned to the last page with all variables (of all previous pages) prefilled, including current error messages ("Please choose ..."), if there where any.
I am trying create a small web application that allows a user to "login" and "logout."
What I am currently having a problem with is allowing the client to send constant "heartbeats" or messages to the server to notify that it is still active.
This is more of a logical question. What I want to do is have a while(1) loop in php that checks if n number of heartbeats have been skipped. I still want the client and server to be able to interact while this loop is going on (essentially I want the server to behave as if it has a separate "check_for_heartbeats" thread.
How does one accomplish this using php? I am running XAMPP at the moment. Any help would be much appreciated.
Edit: To clarify, what I want to do is be able to catch a browser close event even on instances where the window.unload event won't fire (e.g. a client gets disconnected from the internet). In this case, having a thread to monitor heartbeats seems to be the most intuitive solution, though I'm not sure how to make it happen in php.
Edit 2: isLoggedIn() is just helper function that checks to see if a session boolean variable ($_SESSION['is_logged_in')) is set.
Edit Final: Okay, so I now understand exactly what the comments and responses were saying. So to paraphrase, here is the potential solution:
Have Javascript code to send "heartbeats" to the server. The server will add a timestamp associated with these beats.
Modify the database to hold these time stamps
Query the entire "timestamps" table (more likely a 'users' table with a 'timestamp' attribute), and see if the difference between NOW and last timestamp is greater than some threshold.
"Log off" any users passed this threshold.
The only issue is if there is just one user logged in or if all users lose connection at the same time - but in these cases, no one else will be there to see that a user has lost connection.
This is a combination of multiple responses, but I think chris's response takes care of the majority of the issue. Thank you to both chris and Alex Lunix for the helpful contributions. :D
Here is a code snippet for a better explanation
Server Side:
function checkBeats()
{
while(isLoggedIn())
{
// it's been > 30 secs since last heartbeat
if((time() - $_SESSION['heartbeat']) > 30)
{
logout();
break;
}
}
}
What i usually do is call a php file using javascript (jQuery) and update a database or whatevery you like. This question might answer yours: Whats the easiest way to determine if a user is online? (PHP/MYSQL)
You could use ajax to heartbeat a script that changes the heartbeats session variable, and just at the top of every script do this check (put it in a function and call that of course):
// it's been > 30 secs since last heartbeat
if((time() - $_SESSION['heartbeat']) > 30)
{
logout();
}
Edit:
If you want the database to reflect that status instantly instead of when they next visit the page, you'll need to use MySQL. Without using another program (such as a java program) to check the database the only thing I can think of is to add this at the top of every page (in a function that gets called of course):
mysql_query("UPDATE `users` SET `loggedin`=0 WHERE heartbeat<".time()-30);
Which would update every user, which means the accuracy of the loggedin value would be set by the frequency of page views.
Is there a way to detect when someone leaves your site? So far I know about using ignore_user_abort() but thats about as far as I've gotten.
The reason I need to know this is because I need a script to execute upon someone leaving the site.
Record a timestamp in a database for each user and update this upon each page load (or through AJAX).
When the last updated timestamp is older than a cetain amount of time (30 mins?) you can consider they've left the site and do your code, deleting the entry afterwards.
Idea: a "user" could be a primary key made up of their IP and user agent as an MD5 hash for example.
1) I've found the Session Timeout Warning PHP Example with jQuery/JS article
2) Session timeout in PHP thread
3) Also article on how to do it with jQuery and ColdFusion
I can be done easily using javascript, check this solution
<body onbeforeunload="winCloseFunc();"> =)
Due to the stateless nature of http, there isn't an easy way to tell when someone leaves a site. It is possible to trigger onUnload when they leave a page, but this also fires as they navigate from page to page on your site.
Mozilla's Ref: https://developer.mozilla.org/en/DOM/window.onunload
MS's Ref: http://msdn.microsoft.com/en-us/library/ms536907(v=vs.85).aspx
Normally a session is setup to just expire when the user hasn't been seen in X minutes.
I need to perform an action after a session times out. However I have no clue how to trigger that action without an incoming request. An event handler/a listener/a timer would suit perfect but since PHP does not support such a thing it is really difficult to accomplish what I want.
After lot of searching I bumped into session_set_save_handler but I still cannot fully understand how this method works. If I write code that triggers the action inside the close method when it will be executed?
I also need to keep the current session solution as it is and I wonder what the ramifications of using session_set_save_handler in conjunction with that will be? (My current solution sets a session cookie, assigns a name to the session and starts the session, when the user logs out or a request is done after the session timeout (that value is set in a configuration file) the session is completely destroyed)
Regards!
This is somewhat difficult to do in php, AFAIK.
But you can try by making a passive session handler:
Store session ids associated with a timestamp.
Each time the user associated with certain id makes a request, refresh it's timestamp.
You can detect defunct sessions by comparing the system's current, and each session id's timestamps. The ones that differ above a given treshold (say 30min), are assumed to have passed away. Then you can execute your own save handlers for these session ids.
This won't work if the session end handler needs to be executed inmediately, as this process is executed each time when a request arrives (from any user), so it will depend directly on the website's traffic flow.
But you can also solve it by setting cron jobs each 15min or so. Depending on how expensive your save handlers are, seems an acceptable periodicity.
PHP needs to run in some way for PHP code to execute. Either through a user request or a cronjob.
A Session is saved to the locale storage when a PHP request finishes executing or when session_write_close() is called
This session_set_save_handler() allows you to write your own save handler.