skip to Main Content

(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?

2

Answers


  1. Magic getters/setters only trigger for non existing properties. Quote: https://www.php.net/manual/en/language.oop5.overloading.php#object.set -> __set() is run when writing data to inaccessible (protected or private) or non-existing properties..

    So in your example, at first the public variables does exist. After unset, the public variable does not exist/unintialized and magic getter/setter come into place.

    I think this behaviour is still wrong because the property exist but it is uninitialized. Should be maybe a bug report?

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search