ID:               36424
 Updated by:       [EMAIL PROTECTED]
 Reported By:      mastabog at hotmail dot com
 Status:           Open
 Bug Type:         SPL related
 Operating System: *nix, win32
 PHP Version:      5.1.2, 5.1.3rc2-dev
 New Comment:

To make this fail, it needs to be

    $this->assertEquals(true, $new_oC->A === $new_oC->B->A);



Previous Comments:
------------------------------------------------------------------------

[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

Reply via email to