I have a web app that stores some objects in the user session so it doesn't have to keep calling to the database every time there's an AJAX hit to the server.

I want to write some cleanup/save functions that are triggered when the user closes the browser tab or navigates away from the page.

Is the session "destroyed" (i.e. calls __destruct for any objects it contains) if a user navigates away from the page - or is it better to handle this client side with a javascript that sends an AJAX request when the user navigates away?

Destructors are called when the objects are destroyed. In PHP, this means they are called, at the latest, when a script has finished executing. If a client navigates away from the page, there's nothing telling PHP that's happened - unless you have some sort of polling mechanism checking if the user has left.
–
NullUserExceptionOct 13 '12 at 23:13

Or in layman terms: __destruct gets called right before the script/page is done loading, and no communication with php happens after the page is served (unless there's polling like @NullUserException suggests)
–
MahnOct 13 '12 at 23:17

4 Answers
4

The session is in PHP is not defined as a class. Instead, we have a set of session functions to manipulate the session. To make sure that you have destroyed the session, you need to explicitly call :

session_destroy();

If you have not destroyed the session, the session will do garbage collection after the session timeout. The garbage collection depends on the following parameters - session.gc_maxlifetime, session.gc_divisor and session.gc_probability. To make sure that the garbage collection runs on every session, you will have to add session.gc_probability to 100%. But it definitely add an overhead to the server, especially if yours is a high traffic server.

If you do not explicitly keep track of the sessions and destroy it after use, you are leaving some part of the session management to the OS. See the note from PHP.net:

Note: If you are using the default file-based session handler, your
filesystem must keep track of access times (atime). Windows FAT does
not so you will have to come up with another way to handle garbage
collecting your session if you are stuck with a FAT filesystem or any
other filesystem where atime tracking is not available. Since PHP
4.2.3 it has used mtime (modified date) instead of atime. So, you won't have problems with filesystems where atime tracking is not
available.

The best way is to send a flag via Ajax call when the browser or tab is closed. You can detect it via : window.onunload event of javascript.

If you put any objects into $_SESSION, their destructors are NOT called when the script ends, but if it exists, the magic function __sleep() is calles when PHP serializes $_SESSION. When the next scripts starts the session again, any object that is stored and whose source code is known (e.g. by requiring it before calling session_start(), or using autoloading) will have the __wakeup() method called.

If PHP detects that a session was inactive for a certain time, it simply deletes the serializes file.