奇怪的__set()魔术功能

Vla*_*ban 5 php

任何人都可以解释一下这种行为的逻辑吗?

考虑以下情况:

class EPPDomain
{
    protected $myField;

    public static function buildEPPDomain($fieldValue)
    {
        $me = new self();
        $me->myField = $fieldValue;
        return $me;
    }

    public function __set($name, $value)
    {
        $this->$name = "prefix_".value;
    }
}

class EPPDomainFactory
{
    public static function buildEPPDomain($fieldValue)
    {
        $me = new EPPDomain();
        $me->myField = $fieldValue;
        return $me;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以

$dmn = EPPDomain::buildEPPDomain("myValue");
echo $dmn->myField;
Run Code Online (Sandbox Code Playgroud)

预期

prefix_myValue
Run Code Online (Sandbox Code Playgroud)

实际

myValue
Run Code Online (Sandbox Code Playgroud)

明显,

$dmn = EPPDomainFactory::buildEPPDomain("myValue");
echo $dmn->myField;
Run Code Online (Sandbox Code Playgroud)

按预期输出工作

prefix_myValue
Run Code Online (Sandbox Code Playgroud)

根据http://www.php.net/manual/en/language.oop5.overloading.php#object.set上的__set描述

将数据写入不可访问的属性时运行__set().

当我在EPPDomain类的静态方法中创建EPPDomain的实例时,所有受保护的属性都应该是不可访问的.因此应调用__set,但不是

我知道它也说

属性重载仅适用于对象上下文.这些魔术方法不会在静态上下文中触发.因此,不应将这些方法声明为静态.从PHP 5.3.0开始,如果其中一个魔术重载方法被声明为静态,则会发出警告.

但我有一个表达式,它只是声明__set方法应该是一个类成员函数,不应该是静态的.就是这样,它似乎与我所面临的情况无关.

这是一个错误或预期的行为?

dec*_*eze 5

一个protected属性是可访问在相同或继承的所有代码的类.重点是课堂.

class Foo {

    protected $bar;

    public function foo() {
        $foo = new self;
        $foo->bar = 'baz';
    }

}
Run Code Online (Sandbox Code Playgroud)

这很好用.该正在上一个实例的本身,它可以访问自己的属性.这不是关于"外国事例",而是关于阶级.

受保护属性的要点是它们的存在或实现应该只与定义它们的类相关.其他代码不应该直接搞乱它们.由于可以假设类知道如何处理自己的属性,因此可以信任类来操纵其类型的任何对象的属性.