我有一个非常特殊的情况,需要从类外部调用受保护的方法。虽然我在编程方面非常谨慎,但在这个特殊情况下,我不完全反对这样做。在所有其他情况下,我需要继续禁止访问内部方法,因此我想保持该方法受保护。
有哪些优雅的方法可以在类外部访问受保护的方法?到目前为止,我发现了这个。
我想可能可以创建一种目标类的双重代理实例,以偷偷地提供对内部内容的访问...
我有一个非常特殊的情况,需要从类外部调用受保护的方法。虽然我在编程方面非常谨慎,但在这个特殊情况下,我不完全反对这样做。在所有其他情况下,我需要继续禁止访问内部方法,因此我想保持该方法受保护。
有哪些优雅的方法可以在类外部访问受保护的方法?到目前为止,我发现了这个。
我想可能可以创建一种目标类的双重代理实例,以偷偷地提供对内部内容的访问...
在PHP中,您可以使用Reflections来实现这一点。要调用受保护或私有方法,请使用setAccessible()方法http://php.net/reflectionmethod.setaccessible(将其设置为TRUE即可)
我认为在这种情况下,重构代码以避免需要这样的方法可能是最优雅的方式。当然,一种选择是使用__call
,并在其中解析debug_backtrace
以查看调用该方法的类。然后检查好友白名单。
class ProtectedClass {
// Friend list
private $friends = array('secret' => array('FriendClass'));
protected function secret($arg1, $arg2) {
// ...
}
public function __call($method, $args) {
$trace = debug_backtrace();
$class = $trace[1]['class'];
if(in_array($class, $this->friends[$method]))
return $this->$method($args[0], $args[1]);
throw new Exception();
}
}
这有点笨拙,但可能是一个选项。
添加一个子类以便访问您的受保护的函数
public class Child extends Parent {
public function protectedFunc() {
return parent::protectedFunc();
}
}
接着,在需要调用该函数的地方实例化一个Child
的实例,而不是Parent
。
我只是随便提一下,因为我已经两年没有用PHP编程了。你能否向类中添加一个函数来调用受保护的方法,就像这样?
$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');
编辑: 我认为Tom在查看create_function的文档时是正确的。当您尝试使用此示例调用它时,$this的作用域似乎会出现“错误”。
看起来传统匿名函数从PHP 5.3.0开始也被支持了(我的第一个解决方案可能不起作用),所以我可能会这样编写:
$obj->publicFunc = function($arg) {
return $this->protectedFunc($arg);
};
我认为这样看起来更加清晰(当然,你选择的IDE会更好地突出它)。
我试着使用反射来调用方法,但是PHP也不允许这样做。看起来你需要像其他帖子中建议的那样使用某种子类。如果你找到了一个可行的方法,开发人员可能会在未来将其归类为错误,并在升级到下一个版本时破坏你的代码。
我建议扩展这个类。
如果我必须调用私有函数,我会考虑程序设计上的问题是什么?
曾经有这样的情况:
通过找到任何绕过这些问题的方法,你离真正的解决方案还有很远的路要走。
假设您的方法声明如下:
protected function getTheFoo() {
...
}
protected function setTheFoo($val) {
...
}
使用方法:
$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');
这将绕过受保护的方法并直接访问实例变量。