我有一个非常特殊的情况,我需要从类外部调用受保护的方法。我非常清楚自己在编程方面所做的事情,但在我遇到的这种特殊情况下,我不会完全反对这样做。在所有其他情况下,我需要继续禁止访问内部方法,因此我希望保护该方法。
有哪些优雅的方法可以访问类之外的受保护方法?到目前为止,我已经找到了这个。
我想可能会创建某种目标类的双重代理实例,它会偷偷地提供对内部的访问......
我有一个非常特殊的情况,我需要从类外部调用受保护的方法。我非常清楚自己在编程方面所做的事情,但在我遇到的这种特殊情况下,我不会完全反对这样做。在所有其他情况下,我需要继续禁止访问内部方法,因此我希望保护该方法。
有哪些优雅的方法可以访问类之外的受保护方法?到目前为止,我已经找到了这个。
我想可能会创建某种目标类的双重代理实例,它会偷偷地提供对内部的访问......
在 PHP 中,您可以使用反射来做到这一点。要调用受保护或私有方法,请使用 setAccessible() 方法 http://php.net/reflectionmethod.setaccessible(只需将其设置为 TRUE)
我认为在这种情况下,进行重构以使您不需要这种事情可能是最优雅的方式。说一个选项是__call
在该解析debug_backtrace
中使用并查看哪个类调用了该方法。然后检查一个朋友 whitelst
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);');
编辑: 我认为汤姆在查看 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');
这绕过了受保护的方法,直接进入实例变量。