关于PHP Magic方法__get和__set继承

时间:2013-04-15 16:17:57

标签: php oop inheritance magic-methods

OBS:我在这里直接编码,因为我的代码要复杂得多。

如果我编码:

class SuperFoo {
    public function __get($name) {
        return $this->$name;
    }
    public function __set($name, $value) {
        $this->$name = $value;
    }
}

class Foo extends SuperFoo {
    private $bar = '';
}

$foo = new Foo();
$foo->bar = "Why it doesn't work?";
var_dump($foo);

结果:

object(Foo) {
    ["bar":"Foo":private]=> 
        string(0) ''
}

而不是:

object(Foo) {
    ["bar":"Foo":private]=> 
        string(20) 'Why it doesn't work?'
}

为什么会这样?我不想使用数组来保存属性,因为我需要将它们声明为个人私有成员。

3 个答案:

答案 0 :(得分:5)

您的代码应该导致致命错误,因为您正在尝试访问私有财产。在此之前,您应该收到语法错误,因为您没有正确声明您的函数。因此,你“结果”var转储永远不会发生。

编辑:

您已编辑过您的问题。 它不起作用的原因是因为barFoo 的私密性(SuperFoo无法访问它)。改为protected

答案 1 :(得分:2)

如果对象具有名为$name的属性,则

__get($name) 不会被调用,但会尝试直接使用该属性。并且您的属性是私有的,因此错误。

  

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

     

__ get()用于从不可访问的属性中读取数据。

答案 2 :(得分:1)

如果 Foo :: bar 私有 Foo 需要覆盖 __ get __ set < / strong>即可。这是因为 SuperFoo 无法访问 Foo 的私人成员。以下代码有效,但很难看:

class SuperFoo {
    public function __get($name) {
        return $this->$name;
    }

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

class Foo extends SuperFoo {
    private $bar = '';

    public function __get($name) {
        return $this->$name;
    }

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

正确的解决方案是将 Foo :: bar 的可见性修改为受保护的。现在 SuperFoo 可以访问 Foo :: bar ,因此无需在中覆盖 __ get __ set

class SuperFoo {
    public function __get($name) {
        return $this->$name;
    }

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

class Foo extends SuperFoo {
    protected $bar = '';
}

<强> Check out the PHP Documentation on visibility