【发布时间】:2020-05-02 10:09:30
【问题描述】:
(编辑了这个问题,旧版本引用了RFC的错误版本。)
PHP 中的RFC for typed properties 表示“如果类型化属性是unset(),那么它将返回到未初始化状态。”但是,在 PHP 7.4(至少到 7.4.5)中,当类实现 __set() 时,它的行为似乎确实有所不同,因此它与(原始)未初始化状态不完全相同。第一次设置未初始化的属性时不会调用魔术函数,但在取消设置后再次设置属性时会(意外地)调用它。 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`.
我是否忽略了什么?这是 PHP 当前如何为类型化属性实现 unset() 的错误吗?还是应该在第一次设置未初始化的类型属性时调用__set()?
【问题讨论】:
-
认为它是 - 当一个普通的对象属性未设置时,它会导致在随后访问时调用魔术获取......(在 RFC 中)
-
那是关于魔法get,而我的问题是魔法set。我不确定你从哪里得到这句话,但来自 Progman 发布的链接:“如果一个类型化的属性处于未初始化状态,要么是因为它还没有被初始化,要么是因为它已经显式地 unset(),然后从此属性读取将调用 __get() 方法(如果存在),与普通属性的行为一致。”所以那句话的本意就是原来的未初始化状态和unset()之后的状态是等价的。
-
这是同一个问题的另一个角度:在
$x = new X()之后,从$x->y读取 将调用__get(),但写入它不会 调用__set(),不一致。