EDIT: Problem is a documented php bug by now: https://bugs.php.net/bug.php?id=71617 thanks to for finding that one @Danack
I'm just migrating an application from PHPH 5.5 to PHP 7 and stumbled over some strange behavior when it comes to serializing objects.
I have tried to cook it down to a minimal, complete and verifiable example which can be found at http://sandbox.onlinephpfunctions.com/code/e926a7398119ea715531cafe4ce6a22c329e53b8
The problem is that if a class extends ArrayObject then all private properties seem to just vanish if you serialize()
and then unserialize()
that object:
- create a class with a private property and getter/setter method for that property
- create an object of that class
- set private property via setter method
serialize()
objectunserialize()
result of step 4- call getter method of private property, result depends on your PHP version
- PHP 5.3 - PHP 5.6: result is value set in step 3
- PHP 7: result is null
I have tried to cook it down to a minimal, complete and verifiable example which can be found at http://sandbox.onlinephpfunctions.com/code/e926a7398119ea715531cafe4ce6a22c329e53b8 where you can test the code with different PHP versions.
<?php
class demoStdObject {
public $public = ''; protected $protected = ''; private $private = '';
public function getPublic() { return $this->public; }
public function getProtected() { return $this->protected; }
public function getPrivate() { return $this->private; }
public function setPublic($public) { $this->public = $public; }
public function setProtected($protected) { $this->protected = $protected; }
public function setPrivate($private) { $this->private = $private; }
}
class demoArrayObject extends ArrayObject {
public $public = ''; protected $protected = ''; private $private = '';
public function getPublic() { return $this->public; }
public function getProtected() { return $this->protected; }
public function getPrivate() { return $this->private; }
public function setPublic($public) { $this->public = $public; }
public function setProtected($protected) { $this->protected = $protected; }
public function setPrivate($private) { $this->private = $private; }
}
$arrayObject = new demoArrayObject();
$stdObject = new demoStdObject();
testSerialize($arrayObject);
echo str_repeat('-',30) . "\n";
testSerialize($stdObject);
function testSerialize($object) {
$object->setPublic('public');
$object->setProtected('protected');
$object->setPrivate('private');
$serialized = serialize($object);
$unserialized = unserialize($serialized);
echo get_class($object) . ":\n";
echo $unserialized->getPublic() . "\n";
echo $unserialized->getProtected() . "\n";
echo $unserialized->getPrivate() . "\n";
}
Output for PHP 5.6:
demoArrayObject:
public
protected
private
------------------------------
demoStdObject:
public
protected
private
Output for PHP 7:
demoArrayObject:
public
protected
------------------------------
demoStdObject:
public
protected
private
I could not find any documented changes related to serialize()
, unserialize()
or the ArrayObject
class so I am wondering what's going on. Is it a bug? Undocumented feature? ;-)
As we do a lot of serialize()
/ unserialize()
in our project I really need to make sure bahavior of PHP 7 is 100% compatible to PHP 5.3+ behavior.
Question: How can I make PHP 7 behave like PHP 5.3+??