note 46269 added to function.serialize
| From: | jan at bestbytes dot de | Date: | Tue, 05 Oct 2004 08:58:18 +0000 |
| Subject: | note 46269 added to function.serialize | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-78013@lists.php.net to get a copy of this message | ||
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);
}
?>
----
Manual Page -- http://www.php.net/manual/en/function.serialize.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+46269
Delete -- http://master.php.net/manage/user-notes.php?action=delete+46269&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+46269&report=yes
Search -- http://master.php.net/manage/user-notes.php