简体   繁体   English

关于PHP Magic方法__get和__set继承

[英]About PHP Magic Methods __get and __set on inheritance

OBS: I coded directly here, beacause my code is much more complex. OBS:我在这里直接编码,因为我的代码要复杂得多。

If I code: 如果我编码:

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

Results in: 结果是:

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

And not in: 而不是:

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

Why this happen? 为什么会这样? I don't want to use an array to hold the attributes, because I need them declared as individual private members. 我不想使用数组来保存属性,因为我需要将它们声明为单独的私有成员。

Your code should be resulting in a fatal error because you're trying to access a private property. 您的代码应该导致致命错误,因为您正在尝试访问私有属性。 Even before that, you should receive a syntax error because you haven't properly declared your functions. 在此之前,您应该收到语法错误,因为您没有正确声明您的函数。 Hence, you're "resulting" var dump can never occur. 因此,你“结果”var转储永远不会发生。

Edit: 编辑:

You've edited your question. 你已经编辑了你的问题。 The reason it doesn't work is because bar is private to Foo ( SuperFoo cannot access it). 它不起作用的原因是因为barFoo私有的SuperFoo无法访问它)。 Make it protected instead. 改为使其protected

__get($name) isn't called if object has attribute called $name , but it tries to use the attribute directly. 如果object具有名为$name属性, 则不会调用__get($name) ,但它会尝试直接使用该属性。 And your attribute is private, thus error. 你的属性是私有的,因此是错误的。

__set() is run when writing data to inaccessible properties. 将数据写入不可访问的属性时运行__set()。

__get() is utilized for reading data from inaccessible properties. __get()用于从不可访问的属性中读取数据。

If Foo::bar is private , Foo needs to override __get and __set . 如果Foo :: bar私有的Foo需要覆盖__get__set This is because SuperFoo can't access private members of Foo . 这是因为SuperFoo无法访问Foo的私有成员。 The following code works but it's ugly: 以下代码有效,但很难看:

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

The proper solution is to modify Foo::bar visibility to protected . 正确的解决方案是将Foo :: bar可见性修改为protected Now SuperFoo has access to Foo::bar so there's no need to override __get and __set in Foo . 现在SuperFoo可以访问Foo :: bar,因此不需要在Foo中覆盖__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 查看有关可见性的PHP文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM