如何在服务器超时时保存$ _SESSION变量

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:

  1. 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.

  2. 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)?

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.

$_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.