Несколько дней назад я потратил некоторое время на отладку проблемы и обнаружил странное поведение метода unset () vars и метода magic __set ().
Так вот в чем дело:
class A {
public $var;
public function unsetVar() {unset($this->var);}
}
class B extends A {
public $attr = array();
public function __set($key, $value) {$this->attr[$key] = $value;}
}
$a = new A();
$a->unsetVar();
$a->var = 'teste';
$b1 = new B();
$b1->var = 'teste';
$b2 = new B();
$b2->unsetVar();
$b2->var = 'teste';
var_dump($a, $b1, $b2);
Пример php онлайн: http://goo.gl/CO3Uxj
Это var_dump () возвращает:
object(A)#1 (1) {
["var"]=>
string(5) "teste"}
object(B)#2 (1) {
["attr"]=>
array(1) {
["var"]=>
string(5) "teste"}
}
Таким образом, если сбросить $ a-> var, то переустановка будет работать, как и ожидалось, просто чтобы быть уверенным, что $ b1-> var установит var и не вызовет магический метод, но когда на b2 мы сбросим var, то Волшебный метод будет запущен без сброса $ b2-> var.
Сначала я подумал, что внутренне PHP будет использовать магический метод __set (), чтобы установить переменные, которые не были установлены, используя отражение или какой-то внутренний метод для проверки существования свойства.
Так что, поскольку я переопределил __set (), он запустил бы мой, но не нашел ничего, чтобы поддержать это.
Итак, кто-нибудь знает, почему он так себя ведет?
(с некоторыми документами для поддержки)
Спасибо всем!
unset($var)
уничтожает переменную $var
, делая его недоступным, вызывая уведомление «неопределенная переменная», если вы пытаетесь использовать $var
снова. Уточнить unset()
уничтожает variable
, не value
, а уничтожение переменной означает, что она больше не будет существовать (будет доступна).
Я не смог найти документы, в которых четко указано это, но следующий тест подтверждает мое утверждение (как и ваш тест с __set
).
Я сделал следующее, которое демонстрирует, что __unset()
фактически делает переменные недоступными:
class x {
public $var;
}
$x = new x();
echo '<pre>';
print_r(get_object_vars($x)); //prints Array([var] =>)
echo '<br>';
unset($x->var); //prints Array()
print_r(get_object_vars($x));
Так, get_object_vars
документы заявляют:
Получает доступные нестатические свойства данного объекта в соответствии с областью действия.
а также __set
, документы государства:
запускается при записи данных в недоступные свойства.
а также unset()
, документы государства:
уничтожает указанные переменные
Из чего я делаю вывод: «уничтожить» = «сделать переменную недоступной», потому что если unset
сделал что-то кроме того, чтобы сделать его недоступным, то [var] =>
(или же [var] =>NULL
) был бы напечатан во 2-й раз.
Ответить на ваш вопрос.
Итак, кто-нибудь знает, почему он так себя ведет? (с некоторыми документами для поддержки)
Потому что так и должно быть. В документах просто не указано, как они работают с переменными класса.
Также (необходимы документы), переменные класса являются ссылками на значения, а удаление ссылки уничтожает только ссылку, а не значение (если только это не единственная ссылка на значение).
Редактировать: Вы могли бы возможно сообщить об ошибке документации если вы не удовлетворены этим ответом.
Других решений пока нет …