From: amirlaher at yahoo dot co dot uk Operating system: Debian Sarge,Ubuntu PHP version: 5.2.1 PHP Bug Type: Session related Bug description: session written AFTER global variables have been destroyed
Description: ------------ This issue affects custom session handlers (as defined with session_set_save_handler()), in which the write function attempts to access a *global object*. When upgrading a custom session handler (calling a perl daemon), from php5.1 to php5.2, the session was never written owing to a "Call to a member function xxx() on a non-object" error. This seemingly occurs because global objects get destructed *before* session_write_close() is called, during php's shutdown sequence. I worked around the issue using register_shutdown_function("session_write_close"); near the top of the script. register_shutdown_function() does take effect when a script is terminated using exit(); I would have to call "session_write_close();" after having finished writing to the session. This error also still springs up sometimes when the memory limit is reached. This behaviour-change was painful but could be an intentional change by the php team (?) I am reporting it because it may be an unintentional change, and I have seen that it has also affected other users including Drupal users (e.g. this Zend Forums thread: http://www.zend.com/forums/index.php?t=msg&th=3464 and Drupal: http://drupal.org/node/92802) Cheers Amir Reproduce code: --------------- <?php //apologies: this is more than 20 lines. //I have amended the php manual example to use a rudimentary object, just for illustration purposes. class sess { var $savePath; var $id; function getSavePath() { return $this->savePath; } function setSavePath($savePath) { $this->savePath= $savePath; } function getFilePath() { return $this->getSavePath().'/sess_'.$this->getId(); } function getId() { return $this->id; } function setId($id) { $this->id= $id; } } function open($savePath, $session_name) { global $sess; $sess= new sess; $sess->setSavePath('/tmp'); return(true); } function close() { return(true); } function read($id) { global $sess; $sess->setId($id); if(file_exists($sess->getFilePath())) { return (string) file_get_contents($sess->getFilePath()); } } function write($id, $sess_data) { global $sess; if ($fp = fopen($sess->getFilePath(), "w")) { $return = fwrite($fp, $sess_data); fclose($fp); return $return; } else { return(false); } } function destroy($id){ global $sess; return(unlink($sess->getFilePath())); } function gc($maxlifetime) { global $sess; foreach (glob($sess->getSavePath()."/sess_*") as $filename) { if (filemtime($filename) + $maxlifetime < time()) { unlink($filename); } } return true; } session_set_save_handler("open", "close", "read", "write", "destroy", "gc"); session_start(); print "session id : " . session_id() . "<br>"; if(!$_SESSION['hi']) { $_SESSION['hi']='ho'; } else { $_SESSION['ts']=time(); } print "session data: <pre>"; print_r($_SESSION); print "\nclass data: \n "; print_r($sess); Expected result: ---------------- session written ok Actual result: -------------- session id : 8b2596bea65174ce950bb47140edfe2a session data: Array ( [hi] => ho ) class data: sess Object ( [savePath] => /tmp [id] => 8b2596bea65174ce950bb47140edfe2a ) Fatal error: Call to a member function getFilePath() on a non-object in /var/www/sesstest.php on line 52 -- Edit bug report at http://bugs.php.net/?id=41230&edit=1 -- Try a CVS snapshot (PHP 4.4): http://bugs.php.net/fix.php?id=41230&r=trysnapshot44 Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=41230&r=trysnapshot52 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=41230&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=41230&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=41230&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=41230&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=41230&r=needscript Try newer version: http://bugs.php.net/fix.php?id=41230&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=41230&r=support Expected behavior: http://bugs.php.net/fix.php?id=41230&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=41230&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=41230&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=41230&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=41230&r=php3 Daylight Savings: http://bugs.php.net/fix.php?id=41230&r=dst IIS Stability: http://bugs.php.net/fix.php?id=41230&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=41230&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=41230&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=41230&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=41230&r=mysqlcfg