в php я сбрасываю свойство объекта, но после десериализации свойство возвращается, почему? - PullRequest
0 голосов
/ 14 ноября 2018

Мой код 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 голосов
/ 14 ноября 2018

Когда вы вызываете unserialize, будет создан новый объект.Это не совсем тот же объект.

У вашего класса есть значения по умолчанию, поэтому, когда вы десериализуете объект и у вас не установлено свойство $ 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);
0 голосов
/ 14 ноября 2018

unserialize создает и инициализирует новый экземпляр класса (хотя он не вызывает конструктор), а затем отображает любые значения свойств из сериализованной строки поверх. Поскольку вы полностью удаляете свойство, не существует значения для отображения по умолчанию, и поэтому оно остается установленным в вашем новом объекте.

Если для свойства задано значение null, а не его сброс, то оно все равно будет сохранено в сериализованной копии, и поведение должно закончиться так, как вы предполагали.

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

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

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

объект (тест) # 3 (3) { [ "А"] => НОЛЬ [ "Ь"] => строка (1) "b" [ "С"] => строка (1) "с" }

объект (тест) # 4 (3) { [ "А"] => строка (1) "а" [ "Ь"] => строка (1) "b" [ "С"] => строка (1) "с" } * +1010 *

(Разница в том, что восстановленному объекту все равно будет присвоено свойство a, равное нулю, что не является вполне таким же, как при его отключении, но должно вести себя так же в большинстве ситуаций)

В качестве более сложного решения (или, если оно не соответствует ожидаемому вами поведению), вы можете использовать в своем классе магические методы PHP __sleep и __wakeup в своем классе. , который дает вам более детальный контроль над тем, что происходит, когда объект сериализуется / не сериализуется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...