From: mastabog at hotmail dot com
Operating system: *nix, win32
PHP version: 5.1.2
PHP Bug Type: SPL related
Bug description: Serializable interface breaks object references
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 bug report at http://bugs.php.net/?id=36424&edit=1
--
Try a CVS snapshot (PHP 4.4):
http://bugs.php.net/fix.php?id=36424&r=trysnapshot44
Try a CVS snapshot (PHP 5.1):
http://bugs.php.net/fix.php?id=36424&r=trysnapshot51
Try a CVS snapshot (PHP 6.0):
http://bugs.php.net/fix.php?id=36424&r=trysnapshot60
Fixed in CVS: http://bugs.php.net/fix.php?id=36424&r=fixedcvs
Fixed in release:
http://bugs.php.net/fix.php?id=36424&r=alreadyfixed
Need backtrace: http://bugs.php.net/fix.php?id=36424&r=needtrace
Need Reproduce Script: http://bugs.php.net/fix.php?id=36424&r=needscript
Try newer version: http://bugs.php.net/fix.php?id=36424&r=oldversion
Not developer issue: http://bugs.php.net/fix.php?id=36424&r=support
Expected behavior: http://bugs.php.net/fix.php?id=36424&r=notwrong
Not enough info:
http://bugs.php.net/fix.php?id=36424&r=notenoughinfo
Submitted twice:
http://bugs.php.net/fix.php?id=36424&r=submittedtwice
register_globals: http://bugs.php.net/fix.php?id=36424&r=globals
PHP 3 support discontinued: http://bugs.php.net/fix.php?id=36424&r=php3
Daylight Savings: http://bugs.php.net/fix.php?id=36424&r=dst
IIS Stability: http://bugs.php.net/fix.php?id=36424&r=isapi
Install GNU Sed: http://bugs.php.net/fix.php?id=36424&r=gnused
Floating point limitations: http://bugs.php.net/fix.php?id=36424&r=float
No Zend Extensions: http://bugs.php.net/fix.php?id=36424&r=nozend
MySQL Configuration Error: http://bugs.php.net/fix.php?id=36424&r=mysqlcfg