从 PHP 中的类外部调用受保护的方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/982518/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Call a protected method from outside a class in PHP
提问by Chad Johnson
I have a very special case in which I need to call a protected method from outside a class. I am very conscious about what I do programmingwise, but I would not be entirely opposed to doing so in this one special case I have. In all other cases, I need to continue disallowing access to the internal method, and so I would like to keep the method protected.
我有一个非常特殊的情况,我需要从类外部调用受保护的方法。我非常清楚我在编程方面所做的事情,但在我遇到的这种特殊情况下,我并不完全反对这样做。在所有其他情况下,我需要继续禁止访问内部方法,因此我希望保护该方法。
What are some elegant ways to access a protected method outside of a class? So far, I've found this.
在类外访问受保护的方法有哪些优雅的方法?到目前为止,我已经找到了这个。
I suppose it may be possible create some kind of double-agent instance of the target class that would sneakily provide access to the internals...
我想有可能创建某种目标类的双重代理实例,它会偷偷地提供对内部的访问......
回答by Maria
In PHP you can do this using Reflections. To invoke protected or private methods use the setAccessible() method http://php.net/reflectionmethod.setaccessible(just set it to TRUE)
在 PHP 中,您可以使用反射来做到这一点。要调用受保护或私有方法,请使用 setAccessible() 方法 http://php.net/reflectionmethod.setaccessible(只需将其设置为 TRUE)
回答by rojoca
I would think that in this case, refactoring so you don't require this sort of thing is probably the most elegant way to go. In saying that one option is to use __calland within that parse debug_backtraceto see which class called the method. Then check a friends whitelst
我认为在这种情况下,重构使您不需要这种事情可能是最优雅的方式。说一种选择是__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();
}
}
I think I need a shower.
我想我需要洗个澡。
回答by Brock Boland
This is a little kludgy, but might be an option.
这有点笨拙,但可能是一种选择。
Add a child class for the sake of accessing your protected function
添加子类以访问受保护的功能
public class Child extends Parent {
public function protectedFunc() {
return parent::protectedFunc();
}
}
Then, instantiate an instance of Childinstead of Parentwhere you need to call that function.
然后,实例化一个实例Child而不是Parent您需要调用该函数的位置。
回答by Csaba Kétszeri
I'd think about what is the matter with the program design if I have to call a private function?
如果我必须调用私有函数,我会考虑程序设计有什么问题?
It used to be the case when
曾经是这样的
- your class is responsible for several things (it is really two or thre calsses wrapped together) or
- the rules of encapsulation are broken (utility functions, for example)
- 您的班级负责几件事(实际上是将两个或三个课程组合在一起)或
- 封装规则被破坏(例如实用函数)
By finding anyway to walk around this questions, you'll be nowhere nearer to the real solution.
通过找到解决这些问题的任何方法,您将离真正的解决方案更近一步。
回答by Dave L
I'm just throwing this out there since I haven't programmed in PHP in two years. Could you just add a function to the class that calls the protected method like so?
我只是把它扔在那里,因为我已经两年没有用 PHP 编程了。您可以像这样向调用受保护方法的类添加一个函数吗?
$obj->publicFunc = create_function('$arg', 'return $this->protectedFunc($arg);');
Edit: I think Tom's correct in looking at the documentation for create_function. It looks like the scope of $this will be "wrong" when you try to call it with this example.
编辑: 我认为汤姆在查看 create_function 的文档时是正确的。当您尝试使用此示例调用 $this 时,它的作用域似乎是“错误的”。
It looks like traditional anonymous functions are supported since PHP 5.3.0 as well (and my first solution probably won't work), so I'd probably write it like this instead:
从 PHP 5.3.0 开始,似乎也支持传统的匿名函数(而且我的第一个解决方案可能不起作用),所以我可能会这样写:
$obj->publicFunc = function($arg) {
return $this->protectedFunc($arg);
};
Since I think it looks a little cleaner (and your IDE of choice will highlight it better of course).
因为我认为它看起来更干净(当然,您选择的 IDE 会更好地突出显示它)。
Ugh, I tried using Reflectionto call the method but PHP won't allow you to do that either. It seems that you're going to have to use some sort of child class like the other posters have suggested. If you find a method that works, the developers will likely classify it as a bug in the future and break your code when you upgrade to the next version.
呃,我尝试使用反射来调用该方法,但 PHP 也不允许你这样做。似乎您将不得不像其他海报建议的那样使用某种子类。如果您发现一种有效的方法,开发人员可能会在将来将其归类为错误,并在您升级到下一个版本时破坏您的代码。
I recommend extending the class.
我建议扩展课程。
回答by Dave L
Suppose your method declaration goes like so:
假设你的方法声明是这样的:
protected function getTheFoo() {
...
}
protected function setTheFoo($val) {
...
}
Usage:
用法:
$obj->__get('the_foo');
$obj->__set('the_foo', 'myBar');
This bypasses the protected methods and goes directly straight to the instance variables.
这绕过了受保护的方法并直接进入实例变量。

