5

谁能解释一下这种行为的逻辑?

考虑以下情况:

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;
    }
}

所以

$dmn = EPPDomain::buildEPPDomain("myValue");
echo $dmn->myField;

预期的

prefix_myValue

实际的

myValue

明显地,

$dmn = EPPDomainFactory::buildEPPDomain("myValue");
echo $dmn->myField;

按预期输出

prefix_myValue

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

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

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

我知道它也说

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

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

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

4

2 回答 2

5

同一类或继承类中的所有代码都可以访问protected属性。重点放在课堂上。

class Foo {

    protected $bar;

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

}

这工作得很好。该类正在处理自己的实例它可以访问自己的属性。这不是关于“外部实例”,而是关于班级。

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

于 2013-08-08T13:11:33.197 回答
0

这是预期的行为,因为方法确实可以访问其类实例的受保护(甚至是私有)属性。

于 2013-08-08T13:10:03.047 回答