|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2008-09-21 02:22 UTC] ehassler at synapsestudios dot com
Description:
------------
During unserialization of a 3 deep non-recursive but not-a-tree data structure (more like a diamond) where, on nodes in level 2 a __wakeup causes all references to a child node of a certain class to be removed, when that child node would occur in subsequent level 2 nodes' child spots, the reference instead now points to the next level 2 node instead of any level 3 node. More specifically, it points to the first level 2 node after the one that removed said child.
The sample code makes it more clear.
Reproduce code:
---------------
class B {
public $value;
function __construct($value){ $this->value = $value; }
function __wakeup()
{
if($this->value instanceof C)
$this->value = C::$instance;
}
}
class C { static public $instance; }
C::$instance = new C;
$A = array( new B(C::$instance), new B(C::$instance), new B(C::$instance) );
var_dump($A);
$A = unserialize(serialize($A));
var_dump($A);
Expected result:
----------------
array
0 =>
object(B)[2]
public 'value' =>
object(C)[1]
1 =>
object(B)[3]
public 'value' =>
object(C)[1]
2 =>
object(B)[4]
public 'value' =>
object(C)[1]
array
0 =>
object(B)[5]
public 'value' =>
object(C)[1]
1 =>
object(B)[7]
public 'value' =>
object(C)[1]
2 =>
object(B)[8]
public 'value' =>
object(C)[1]
Actual result:
--------------
array
0 =>
object(B)[2]
public 'value' =>
object(C)[1]
1 =>
object(B)[3]
public 'value' =>
object(C)[1]
2 =>
object(B)[4]
public 'value' =>
object(C)[1]
array
0 =>
object(B)[5]
public 'value' =>
object(C)[1]
1 =>
object(B)[6]
public 'value' =>
&object(B)[6]
2 =>
object(B)[7]
public 'value' =>
object(B)[6]
public 'value' =>
&object(B)[6]
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Nov 21 04:00:02 2025 UTC |
After adding static $instance2 to class C, and changing the __wakeup to this: function __wakeup() { if($this->value instanceof C) { C::$instance2 = $this->value; $this->value = C::$instance; } } I get the expected behavior. So, I guess, you know, hope that helps.Very similar problem in PHP_VERSION === '5.2.7RC3-dev' under Windows. I ran my test script and got out: array(3) { [0]=> object(B)#5 (1) { ["value"]=> object(C)#1 (0) { } } [1]=> object(B)#6 (1) { ["value"]=> object(B)#6 (1) { ["value"]=> *RECURSION* } } [2]=> object(B)#7 (1) { ["value"]=> object(B)#6 (1) { ["value"]=> object(B)#6 (1) { ["value"]=> *RECURSION* } } } }