Destructors and session data in the database
One of my projects uses its own session handler to write the session data to the database instead of to the file system. The first step is to mount and call your own functions with session_set_save_handler ().
However, the problem arose here that PHP had already destroyed most of the objects in memory at the time the write function was called, including the object that I use for database access. This is a known and documented problem. The PHP documentation suggests triggering the write handler manually with the following line:
register_shutdown_function (‘session_write_close’);
Shutdown functions are called before the objects are destroyed. This means that my database object is still available when the session is closed and the data can be saved in the database.
The next problem, however, was that the shutdown functions were also called before the destructors. So what happens if a destructor of an object changes data in the session? In my example it was a shopping cart object of a shop system. The shopping cart should save its content at the end of the script in the session. However, by using the register_shutdown_function () trick, the shopping cart is only written to the session after it has already been closed via session_write_close ().
So I came up with the following trick:
class SessionShutdownHelper
{
function __destruct () {session_write_close (); }
}
register_shutdown_function (function ()
{
$ one = new SessionShutdownHelper ();
$ one-> one = $ one;
});
Here session_write_close () is not called directly via a shutdown function, but indirectly via a destructor of an otherwise empty object. The circular reference forces the PHP interpreter to keep the SessionShutdownHelper object in memory until the end of the script, because such combinations can only be removed by the Cycles Collection. This means that session_write_close () is only called after all other destructors, and my shopping cart safely ends up in the database.
