如果属性未退出,则默认为默认的getter行为

时间:2011-03-12 15:26:06

标签: php oop setter getter magic-methods

我目前需要扩展一个类来为它添加功能(我无法访问基类来修改它),而且我正在使用它来运行isssue。

基本上,我需要魔术getter函数来返回一组私有变量(如果请求它们),否则默认为默认行为。我需要这些属性是私有的,以便使用魔术设置器功能自动同步一些数据。

那就是说,这是一些示例代码:

class newClass extends baseClass {
    private $private1;
    private $private2;

    ...

    public function __get($name) {
        if($name == 'private1') return $this->private1;
        if($name == 'private2') return $this->private2;
        ... (and so on)
        // and here, it should default back to it's default behavior (throwing
        // an error on getting invalid/inaccessable property, etc.)
        // I cannot just use property_exists, because there may or may not be
        // private variables in the base class that should not be exposed.
    }
    public function __set($name,$val) {
        // I use this to do some automatic syncing when the two private variables
        // above are set. This needs to be triggered, hence the private variables
        // in the first place.
    }
}

我知道,我可以使用getProperty / setProperty函数,但我希望尽可能保持这种直观,尽管有人认为执行此类操作是违反直觉的。这两个私有财产彼此之间有很多联系。当其中一个被设置时,它在逻辑上会影响其他人。

截至目前,这是我能想到的唯一合理的方法,可以避免getter / setter函数并保持属性之间紧密绑定的同步。如果你们可以想到任何其他可能是可行的解决方案,请随时提出建议:)

2 个答案:

答案 0 :(得分:1)

PHP没有像其他语言一样构建的属性,__ get和__set确实是你应该在这里使用的。但是要完成它还需要做更多的工作。

您的问题似乎是property_exists最重要的。从类中确定属性的公开性是不容易的(除了内省)。但您可以使用get_object_vars至少从基类中过滤掉私有变量:

 function __get($name) {
     static $r; if (!isset($r)) { $r = new ReflectionClass($this); }

     if (($p = $r->getProperty($name)) and $p->isPublic()) {
         return $this->$name;
     }
     elseif (method_exists($this, "get_$name")) {
         return $this->{"get_$name"}();
     }
     else trigger_error("inaccessible property ->$name", E_USER_NOTICE);
 }

要恢复默认行为,您可以做的最好是手动输出错误消息。

答案 1 :(得分:-1)

不要这样做,请使用getter / setter。它们与你在这里的工作量完全相同。