1

我目前需要扩展一个类以向它添加功能(我无权访问基类来修改它),并且我遇到了它的问题。

基本上,如果需要,我需要魔术 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 函数并保持属性之间紧密结合的同步的唯一合乎逻辑的方法。如果你们能想到任何其他可行的解决方案,请随时提出选择:)

4

2 回答 2

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

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

于 2011-03-13T13:45:18.410 回答
-1

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

于 2011-03-12T16:11:18.317 回答