Bug #71617 [Com]: private properties lost when ArrayObject unserialize

From: Date: Wed, 17 Feb 2016 11:57:37 +0000
Subject: Bug #71617 [Com]: private properties lost when ArrayObject unserialize
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-199298@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71617&edit=1 ID: 71617 Comment by: danack@php.net Reported by: janpoem at gmail dot com Summary: private properties lost when ArrayObject unserialize Status: Open Type: Bug Package: Class/Object related Operating System: Windows 10 PHP Version: 7.0.3 Block user comment: N Private report: N New Comment: Without commenting on whether this is a bug or not, your code isn't that safe. Extending a class that implements Serializable and then hoping that properties in the child class are preserved across serialization/deserialization only works by chance - it is not a reliable way of programming. The code below gives an example of where class A serializes/deserializes itself correctly, but doesn't know about class B, so doesn't do what the programmer of class B hoped, which is what you're seeing with ArrayObject. I don't believe there are any guarantees made by ArrayObject (or other classes) that what you are trying to do is going to work. Either using composition rather than inheritance would be much safer, or writing serialize/unserialize methods on the child method would allow you to control the serialization/deserialization. Alternatively, just not using serialize/unserialize and instead using your own interface can also be more predictable than the "magic" internal methods. class A implements Serializable { private $aValue; function __construct($aValue) { $this->aValue = $aValue; } function serialize() { $data = []; $data['aValue'] = $this->aValue; return json_encode($data); } function unserialize($serialized) { $data = json_decode($serialized, true); $this->aValue = $data['aValue']; } } class B extends A { function __construct($aValue, $bValue) { parent::__construct($aValue); $this->bValue = $bValue; } } $obj1 = new B("Give me an A!", "Give me a B!"); $serialized = serialize($obj1); $obj2 = unserialize($serialized); var_dump($obj1); var_dump($obj2); Previous Comments: ------------------------------------------------------------------------ [2016-02-17 09:35:01] janpoem at gmail dot com Description: ------------ The private properties in an ArrayObject will lost when unserialize. Test script: --------------- <?php class Test extends ArrayObject { private $name = null; public function __construct(array $input) { parent::__construct($input, ArrayObject::ARRAY_AS_PROPS); // parent::__construct($input, ArrayObject::STD_PROP_LIST); } public function setName($name) { $this->name = $name; return $this; } public function getName() { return $this->name; } } $test = new Test(['a' => 'a', 'b' => 'b']); $test->setName('ok'); $ser = serialize($test); $unSer = unserialize($ser); var_dump($unSer->getName()); // null var_dump($unSer); // php 7.0.3 /** null object(Test)[2] private 'name' => string 'ok' (length=2) private 'storage' (ArrayObject) => array (size=2) 'a' => string 'a' (length=1) 'b' => string 'b' (length=1) */ // php 5.6.x /** string 'ok' (length=2) object(Test)[2] private 'name' => string 'ok' (length=2) private 'storage' (ArrayObject) => array (size=2) 'a' => string 'a' (length=1) 'b' => string 'b' (length=1) */ ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=71617&edit=1

« previous php.bugs (#199298) next »