我目前需要扩展一个类来为它添加功能(我无法访问基类来修改它),而且我正在使用它来运行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函数并保持属性之间紧密绑定的同步。如果你们可以想到任何其他可能是可行的解决方案,请随时提出建议:)
答案 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。它们与你在这里的工作量完全相同。