ID: 36424 Updated by: [EMAIL PROTECTED] Reported By: mastabog at hotmail dot com -Status: Open +Status: Assigned Bug Type: SPL related -Operating System: *nix, win32 +Operating System: * -PHP Version: 5.1.2, 5.1.3rc2-dev +PHP Version: 5.1.3RC2-dev -Assigned To: +Assigned To: helly New Comment:
Assigned to the SPL maintainer. Previous Comments: ------------------------------------------------------------------------ [2006-03-18 10:30:38] [EMAIL PROTECTED] To make this fail, it needs to be $this->assertEquals(true, $new_oC->A === $new_oC->B->A); ------------------------------------------------------------------------ [2006-03-18 10:29:16] [EMAIL PROTECTED] When playing around with this bug, I discovered this: While var_dump($new_oC->A === $new_oC->B->A); Results into bool(false) $this->assertEquals($new_oC->A, $new_oC->B->A); Does not fail! ------------------------------------------------------------------------ [2006-02-17 06:27:22] mastabog at hotmail dot com Description: ------------ First of all, I know this is very new and undocumented. The Serializable interface serialize() method breaks reference of objects that are properties of the serialized object and that they themselves implement the Serializable interface. See the reproduceable code below. an echo over $ser yields: C:1:"C":85:{a:2:{s:1:"A";C:1:"A":6:{a:0:{}}s:1:"B";C:1:"B":32:{a:1:{s:1:"A";C:1:"A":6:{a:0:{}}}}}} It's visible that the last A is not a reference but a new class instance. I know that Serializable::unserialize() acts as a constructor, but shouldn't object references be honored by Serializable::serialize() the same way unserialize() does when the class does not implement the Serializable interface. If we remove the Serializable interface from class A and leave it like this: class A {} then $ser looks like the following: O:1:"C":2:{s:1:"A";O:1:"A":0:{}s:1:"B";O:1:"B":1:{s:1:"A";r:2;}} And it's visible that the last A is a reference. If this is all intended behavior for the Serializable interface to break object references then you can ignore this bug report. I hope it's not though, because it would have provided a better alternative to the __sleep() and __wakeup() (e.g. classes extending the PDO class cannot be serialized using __sleep() and __wakeup(), neither by overloading nor by default) Reproduce code: --------------- class A implements Serializable { public function serialize () { $serialized = array(); foreach($this as $prop => $val) { $serialized[$prop] = $val; } return serialize($serialized); //return serialize(get_object_vars($this)); } function unserialize($serialized) { foreach(unserialize($serialized) as $prop => $val) { $this->$prop = $val; } return true; } } class B extends A { public $A; } class C extends A { public $A; public $B; } $oC = new C(); $oC->A = new A(); $oC->B = new B(); $oC->B->A = $oC->A; echo $oC->A === $oC->B->A ? "yes" : "no", "\n"; $ser = serialize($oC); $new_oC = unserialize($ser); echo $new_oC->A === $new_oC->B->A ? "yes" : "no", "\n"; Expected result: ---------------- yes yes Actual result: -------------- yes no ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=36424&edit=1