我的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
?
答案 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);