ID: 36424
Comment by: hos dot endre at cafecsoport dot hu
Reported By: mastabog at hotmail dot com
Status: Assigned
Bug Type: SPL related
Operating System: *
PHP Version: 5.1.3RC2-dev
Assigned To: helly
New Comment:
Crashing also reproducable.
Win2000Prof / PHP514
My related problem is that serializing a Serializable object, thats
some object property holds a reference to the serialized root object,
PHP crashes.
The magic function __serialize have too much sideFx for me - making the
object unworkable,
but I cant figure out how nested serialize function calls could work
properly.
Probably when the native serialize function is handles a nested call
then could hook up the root calls pointer map?
And then could this work for nested unserialization?
At this time I have no vision about the sideFx of this mention.
Right now I dont have a prepared C development environment to work out,
and dont remember how the related part of the code workx. As I remember
nested call test was implemented in the __autoload() function.
Since it can cause crashes please take more care on this bug.
Just uncomment 'implements Serializable' to let it crash.
class A // implements Serializable
{
public $dontSerialize;
public $that;
function __construct($that = null)
{
$this->that = ($that === null) ? new A($this) : $that;
}
function serialize()
{
return serialize($this->that);
}
function unserialize($serialized)
{
$this->that = serialize($serialized);
}
}
Previous Comments:
------------------------------------------------------------------------
[2006-04-11 11:43:11] sniper@php.net
Assigned to the SPL maintainer.
------------------------------------------------------------------------
[2006-03-18 10:30:38] nohn@php.net
To make this fail, it needs to be
$this->assertEquals(true, $new_oC->A === $new_oC->B->A);
------------------------------------------------------------------------
[2006-03-18 10:29:16] nohn@php.net
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