Writing to Zend_Session_Namespace in destruct

804 views Asked by At

I'm noticing some slightly unexpected behaviour using __destruct to write data using Zend_Session_Namespace in PHP 5.3:

public function __destruct(){
    $this->getSession()->data = $this->data;
}
// ....
private function getSession()
{
    if (! self::$zendSession) {
        // this next line is fine because the object is a singleton
        self::$zendSession = new Zend_Session_Namespace(self::SESSION_NAMESPACE);
    }
    return(self::$zendSession);
}

The destructor is getting called, but the data isn't getting written. However, if I implicitly call the destruct after the object has had all the necessary operations done on it, and force destruction before script termination, the data is written fine, but I'd rather not do this.

I imagine it has something to do with this bug: http://bugs.php.net/29032 (bug seems a bit old to me), and on the face of it the fix looks good (register __destruct as shut-down function, which is called before $_SESSION is unavailable), but wouldn't the destructor get called twice (once through the register_shutdown_function and once automatically?

Surely writing the odd bit of object data to session on shutdown is a thing that has been solved? What do people do when this is required?

(OSX 10.6.6, Apache 2.2.15 (Unix), PHP 5.3.3, Zend Framework 1.7.2)

1

There are 1 answers

4
Long Ears On BEST ANSWER

This is a chicken and egg problem. If the session termination was left until all objects had been destroyed, then it would be impossible to use an object for the session save handler.

The register_shutdown_function workaround is fine. To avoid running the code twice, you should move your session termination code into a different function which you register. Manually calling __destruct() on an object which still exists seems a bit ugly anyway ;)