在php中,我未设置对象的属性,但是在unserialize之后,该属性又回来了,为什么?

时间:2018-11-14 09:17:37

标签: php serialization

我的PHP代码在这里:

class test {
    public $a = 'a';
    public $b = 'b';
    public $c = 'c';
}
$a = new test();
unset($a->a);
$b = serialize($a);
$c = unserialize($b);
var_dump($a, $b, $c);

为什么$c包含属性a

2 个答案:

答案 0 :(得分:0)

unserialize创建并初始化该类的新实例(尽管它没有调用构造函数),然后将序列化字符串中的所有属性值映射到顶部。因为您要完全取消设置属性,所以没有一个值可以映射回默认值,因此它会在新对象中保持设置状态。

如果将属性设置为null而不是取消设置,则该属性仍将存储在序列化副本中,并且其行为应与预期的相同。

$setToNull = new test;
$unset = new test;

$setToNull->a = null;
unset($unset->a);

var_dump(unserialize(serialize($setToNull)), unserialize(serialize($unset)));
  

object(test)#3(3){     [“ a”] =>     空值     [“ b”] =>     字符串(1)“ b”     [“ c”] =>     字符串(1)“ c”   }

     

object(test)#4(3){     [“ a”] =>     字符串(1)“ a”     [“ b”] =>     字符串(1)“ b”     [“ c”] =>     字符串(1)“ c”   }

(不同之处在于,还原的对象仍将a属性设置为null,这与 quit 设置为null相同,但在大多数情况)

作为更复杂的解决方案(或者如果这与您实际期望的行为不匹配),则可以在类上使用PHP的__sleep and __wakeup magic methods,从而可以更精细地控制内容当对象被序列化/非序列化时发生。

答案 1 :(得分:0)

调用反序列化时,将创建一个新对象。它不是完全相同的对象。

您的类具有默认值,因此当您对一个对象进行反序列化并且未设置$ a属性时,将使用默认值。

要查看区别,请检查此代码

class test {
    public $a = 'a';
    public $b = 'b';
    public $c = 'c';
}

$a = new test();
$a->a= 'property'; // set a to "property"
unset($a->a); // remove a

$b = serialize($a);
$c = unserialize($b); // there is no "a" property set so default value will be used
var_dump($a, $b, $c);

如果您从public $a = 'a';中删除默认值,则它将为空

class test {
    public $a;
    public $b = 'b';
    public $c = 'c';
}



$a = new test();
$a->a= 'property';
unset($a->a);

$b = serialize($a);
$c = unserialize($b);
echo '<pre>';
var_dump($a, $b, $c);