Skip to content
Advertisement

Why does PHP call __set() after unset()ing declared typed property?

(Edited this question, the old version quoted the wrong version of the RFC.)

The RFC for typed properties in PHP says that “If a typed property is unset(), then it returns to the uninitialized state.” However, in PHP 7.4 (at least up to 7.4.5), it does appear to behave differently when the class implements __set(), and thus it’s not exactly like the (original) uninitialized state. The magic function is not called when the uninitialized property is set for the first time, but it is (unexpectedly) called when the property is set again after having been unset. Example code.

<?php

class X {
    public int $y;
    public function __set($name, $value) {
        echo "__set($name, $value) called";
        $this->$name = $value;
    }
}

$x = new X();
$x->y = 42; // Prints nothing, as expected.
unset($x->y);
$x->y = 43; // Prints `__set(y, 43) called`.

Am I overlooking something? Is this a bug in how PHP currently implements unset() for typed properties? Or should __set() even be called when an uninitialized typed property is set for the first time?

Advertisement

Answer

Why?

For the purpose of lazy initialization patterns.

If a typed property is unset(), then it returns to the uninitialized state. While we would love to remove support for the unsetting of properties, this functionality is currently used for lazy initialization by Doctrine

So in PHP 8 they may forbid unsetting of declared properties, after providing some alternative mechanism for lazy initialization.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement