我有两个脚本及其输出:
第一个脚本
class A {
public $view = "foo";
public function getView()
{
return $this->view;
}
}
$a = new A();
$b = serialize($a);
file_put_contents("/tmp/test.tmp",$b);
var_dump($b);
及其输出:
object(A)[1]
public 'view' => string 'foo' (length=3)
string 'O:1:"A":1:{s:4:"view";s:3:"foo";}' (length=33)
比我跑:
第二个脚本
class A {
private $view = "bar";
public function getView()
{
return $this->view;
}
}
$a = unserialize(file_get_contents("/tmp/test.tmp"));
var_dump($a, $a->getView());
并显示:
object(A)[1]
private 'view' => string 'bar' (length=3)
public 'view' => string 'foo' (length=3)
string 'bar' (length=3)
正如您所看到的,唯一的变化是公共$ view变为私有。
我的同事彼得发现了这个,心里一阵:) :)
编辑:
我相信如果你将一些对象(例如通过Doctrine)序列化到DB,这可能真的有问题,而不是更新代码库而不更新存储在DB中的数据(这将成为 - 正如我所假设的 - 解析对象序列化为文本和更新他们使用一些迁移脚本)然后反序列化数据并对其进行处理。我认为这并不罕见,而且这种行为可能是不受控制的。如果未序列化的对象类定义与实际的不同,我很乐意看到PHP抛出错误/异常等。
答案 0 :(得分:4)
它都不是。使用unserialize
表示类的对象的序列化数据,其定义与unserialize
调用环境已知的类定义不同,在PHP文档中根本没有定义。因此,它不是官方功能。但由于没有定义行为和结果,结果也不能被认为是一个错误。
但是如果你真的想把它分成两个类别中的一个" bug"或者"功能",您可能会将其称为未记录的功能,因为它似乎不会使PHP进入PHP脚本执行被破坏的状态"。 (虽然我不会在未来的版本中依赖这种行为 - 但这是一个不同的故事。)
答案 1 :(得分:1)
你可以更快地得到奇怪的结果(demo):
var_dump(unserialize("O:8:\"stdClass\":3:{s:4:\"\0*\0p\";N;s:11:\"\0stdClass\0p\";N;s:1:\"p\";N;}"));
//class stdClass#1 (3) {
// protected $p =>
// NULL
// private $p =>
// NULL
// public $p =>
// NULL
//}
\0
- 0字节字符
这不是一个错误:https://bugs.php.net/bug.php?id=51173
修复此问题会产生更多问题,例如性能下降 解决的问题。
文档可能包含一些关于它的文字,但事实并非如此。