编辑:问题是现在已记录的 php 错误:https://bugs.php.net/bug.php?id=71617 https://bugs.php.net/bug.php?id=71617感谢您找到那个@Danack
我刚刚将应用程序从 PHPH 5.5 迁移到 PHP 7,在序列化对象时偶然发现了一些奇怪的行为。
我试图将其简化为一个最小的、完整的和可验证的示例,可以在以下位置找到:http://sandbox.onlinephpfunctions.com/code/e926a7398119ea715531cafe4ce6a22c329e53b8 http://sandbox.onlinephpfunctions.com/code/e926a7398119ea715531cafe4ce6a22c329e53b8
问题是如果一个类扩展数组对象 http://php.net/manual/en/class.arrayobject.php那么如果你serialize()
进而unserialize()
该对象:
- 创建一个具有私有属性的类以及该属性的 getter/setter 方法
- 创建该类的一个对象
- 通过setter方法设置私有属性
-
serialize()
object
-
unserialize()
步骤 4 的结果
- call getter method of private property, result depends on your PHP version
- PHP 5.3 - PHP 5.6:结果是步骤 3 中设置的值
- PHP 7:结果为空
我试图将其简化为一个最小的、完整的和可验证的示例,可以在以下位置找到:http://sandbox.onlinephpfunctions.com/code/e926a7398119ea715531cafe4ce6a22c329e53b8 http://sandbox.onlinephpfunctions.com/code/e926a7398119ea715531cafe4ce6a22c329e53b8您可以在其中使用不同的 PHP 版本测试代码。
<?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";
}
PHP 5.6 的输出:
demoArrayObject:
public
protected
private
------------------------------
demoStdObject:
public
protected
private
PHP 7 的输出:
demoArrayObject:
public
protected
------------------------------
demoStdObject:
public
protected
private
我找不到与以下内容相关的任何记录的更改serialize()
, unserialize()
or the ArrayObject
类,所以我想知道发生了什么事。这是一个错误吗?未记录的功能? ;-)
正如我们做了很多serialize()
/ unserialize()
在我们的项目中,我确实需要确保 PHP 7 的行为与 PHP 5.3+ 的行为 100% 兼容。
问题:如何使 PHP 7 表现得像 PHP 5.3+?