note 46269 deleted from function.serialize by aharvey

From: Date: Tue, 06 Nov 2012 02:05:41 +0000
Subject: note 46269 deleted from function.serialize by aharvey
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-191751@lists.php.net to get a copy of this message
Note Submitter: jan at bestbytes dot de ---- This should be EXTREMELY helpful when you are getting lost in php 4 circular references and sessions or serializing ... <?php // this example is for php 4 class Node { var $value; var $child; var $parent; var $load; var $__destroyed = false; function Node($value) { $this->value = $value; global $load; $this->load = $load; } function setParent(&$parent) { $this->parent = &$parent; } function setChild(&$child) { $this->child = &$child; } /** * @return void * @desc fake __destroy from a php 4 point of view */ function __destroy() { $props = get_object_vars($this); foreach($props as $propName => $propValue) { unset($propValue); if(is_object($this->$propName)) { if(method_exists($this->$propName, '__destroy') AND $this->$propName->__destroyed !== false) { $this->$propName->__destroy(); } } if(isset($this->$propName)) { unset($this->$propName); } } } } header('Content-type: text/plain'); // small load to check the serialized string $loadSize = 4; // big load to check leaking //$loadSize = 32 * 1024; $load = str_repeat('.', $loadSize); for($i = 0;$i<10;$i++) { echo '-------------------- '.(memory_get_usage()/1024).' -------------------------'.chr(10); $serMe = array(); $serMe['parent'] =& new Node('parent'); $serMe['child'] =& new Node('child'); /* * this will work too !! * $serMe['parent'] = new Node('parent'); * $serMe['child'] = new Node('child'); */ $serMe['parent']->setChild($serMe['child']); $serMe['child']->setParent($serMe['parent']); $str = serialize($serMe); /* * 1.Problem: * * You have 2 or more objects with circular references to one another. * Serializing these objects will result in unexpected behaviour when * unserializing them: * * Former references will become copies. * * This is because the php serialize handler can not handle references, * unless all involved objects, variables ... are within an array(), * that will be serialized. * * This should be selfexplaining (just take a look at the length ...): * echo serialize($serMe['parent']); * echo serialize($serMe); * * results in: * * O:4:"node":5:{s:5:"value";s:6:"parent";s:5:"child";O:4:"node * ":5:{s:5:"value";s:5:"child";s:5:"child";N;s:6:"parent";O:4: * "node":5:{s:5:"value";s:6:"parent";s:5:"child";R:3;s:6:"pare * nt";N;s:4:"load";s:4:"....";s:11:"__destroyed";b:0;}s:4:"loa * d";s:4:"....";s:11:"__destroyed";b:0;}s:6:"parent";N;s:4:"lo * ad";s:4:"....";s:11:"__destroyed";b:0;} * * a:2:{s:6:"parent";O:4:"node":5:{s:5:"value";s:6:"parent";s:5 * :"child";O:4:"node":5:{s:5:"value";s:5:"child";s:5:"child";N * ;s:6:"parent";R:2;s:4:"load";s:4:"....";s:11:"__destroyed";b * :0;}s:6:"parent";N;s:4:"load";s:4:"....";s:11:"__destroyed"; * b:0;}s:5:"child";R:4;} * * PLEASE GIVE THE WORLD PROPER DOCUMENTATION ON THIS (or prove us wrong) * * 2.Problem: * * The loop below will result in extensive leaking (use the big $loadsize ...), * unless you help yourself and unset all the properties manually * see Node::__destroy() * */ $serMe['parent']->__destroy(); $serMe['child']->__destroy(); $serMe = unserialize($str); unset($str); $serMe['parent']->value = 'new parent'; echo '-->'.$serMe['parent']->child->parent->value.chr(10); echo '-->'.$serMe['parent']->value.chr(10); $serMe['parent']->__destroy(); $serMe['child']->__destroy(); unset($serMe); } ?>

« previous php.notes (#191751) next »