|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2004-03-10 18:42 UTC] jaanus at heeringson dot com
Description:
------------
Unable to add session variables from the __destruct() handler in a class. The $_SESSION variable can be accessed and viewed in the __destruct() handler though.
Reproduce code:
---------------
<pre>
<?php
session_start();
class test{
public function __destruct(){
$_SESSION['destructor']='Yes';
}
}
$class=new test();
if(empty($_SESSION['working'])) {
$_SESSION['working']='Yes';
print("New session?\n");
}
print_r($_SESSION);
?>
</pre>
Expected result:
----------------
Array
(
[destructor] => Yes
[working] => Yes
)
Actual result:
--------------
Array
(
[working] => Yes
)
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Wed Nov 05 07:00:01 2025 UTC |
I agree with fschaper. The ability to modify the $_SESSION variable in the destructor could be very useful, for example to have your class automatically serialized in session; this, with a factory pattern (getInstance method, that unserialized the class if exists in session), allow to have a "session object", sort of. for example Class Test{ function __destruct(){ $_SESSION['test'] = serialize($this); } static function getInstance(){ $instance = unserialize($_SESSION['test']); if(!isset($instance) || !is_a$instance,"test")){ $instance = new Test(); } return $instance; } } Actually, this was possible with php 4.x using register_shutdown_function, that (in fact) allows to simulate the destructor behaviour...I agree with fschaper. The ability to modify the $_SESSION variable in the destructor could be very useful, for example to have your class automatically serialized in session; this, with a factory pattern (getInstance method, that unserialized the class if exists in session), allow to have a "session object", sort of. for example Class Test{ function __destruct(){ $_SESSION['test'] = serialize($this); } static function getInstance(){ $instance = unserialize($_SESSION['test']); if(!isset($instance) || !is_a$instance,"test")){ $instance = new Test(); } return $instance; } } Actually, this was possible with php 4.x using register_shutdown_function, that (in fact) allows to simulate the destructor behaviour...This is still a bug. I just upgraded to PHP 5.1.1, using a custom session handler with mysqli, and this is a problem. It appears this is a workaround, albeit I don't think this should be required to function as it did before. I use procedural code, and not object oriented code, so having __destruct handlers do not help me. register_shutdown_function('session_write_close'); Here's my [very simple] session handler. Note db_query() is a simple wrapper for mysqli_query() and handles all the connection details internally. function session_close() { return true; } function session_die($id) { db_query("DELETE FROM session WHERE ID='$id'"); return true; } function session_gc($maxlifetime) { return true; } function session_open($path,$name) { return true; } function session_read($id) { $dchk = db_query("SELECT data FROM session WHERE ID='$id'"); if(db_numrows($dchk) == 1) { if(!isset($_SESSION['row'])) { $_SESSION['row'] = 1; } list($data) = db_rows($dchk); return base64_decode($data); } else { return ""; } db_free($dchk); return true; } function session_write($id,$data) { global $visitor; $data = base64_encode($data); if(!isset($_SESSION['row'])) { db_query("INSERT IGNORE INTO session (ID,data,accessed) VALUES('$id','$data',UNIX_TIMESTAMP(NOW()))"); } else { db_query("UPDATE session SET data='$data',accessed=UNIX_TIMESTAMP(NOW()) WHERE ID='$id'"); } return true; } (fyi: I have a cronjob that does garbage collection based on the "accessed" column) I still think this is a bug, I don't see why this was changed.This bug seems to be affecting the DOM functions as well. <code> class someNode extends DOMNode{ function __destruct() { echo "now I have ".$this->attributes->length." attribute(s)"; } } $x = new someNode('nodename'); $x->setAttribute('bob','frank'); echo "I have ".$x->attributes->length." attributes"; // outputs "I have 1 attribute(s)" unset($x); // outputs "now I have attribute(s)" </code> This behaviour also seems to affect the __construct function as well.Simple, **but annoying** workaround: register_shutdown_function(function(){ session_write_close(); });