您可以在不使用 ReflectionXYZ 类的情况下实现相同的目的
call_user_func( array($this->instance, $action) , $args);
两者都以相同的方式保存,只要您控制 $this->instance 是什么。
$action 是一个字符串,用于搜索对象/类方法哈希表中的条目,并且没有可以转义对象上下文(切换到另一个对象)的魔术符号。并且不涉及解析,例如在 sql 和 sql 注入中。
ReflectionMethod 和 call_user_func_array() 都遵循方法的保护级别。例如
class Foo {
public function publicfn() {
echo 'abc';
}
protected function protectedfn() {
echo 'xyz';
}
}
$obj = new Foo;
call_user_func_array(array($obj, 'publicfn'), array());
call_user_func_array(array($obj, 'protectedfn'), array());
$ro = new ReflectionMethod($obj, 'protectedfn');
$ro->invokeArgs($obj, array());
印刷
abc
Warning: call_user_func_array() expects parameter 1 to be a valid callback, cannot access protected method Foo::protectedfn() in blabla on line 14
Fatal error: Uncaught exception 'ReflectionException' with message 'Trying to invoke protected method Foo::protectedfn() from scope ReflectionMethod' in blabla:16
Stack trace:
#0 blabla(16): ReflectionMethod->invokeArgs(Object(Foo), Array)
#1 {main}
thrown in blabla on line 16
如果总是这样,您可能需要查找。例如有一个 entry - MFH Fixed bug #37816 (ReflectionProperty does not throw exception when accessing protected attribute)
。至少对于 php 5.3 分支是这样。
您始终可以访问 $this->instance 的任何基类的公共方法。
您可以从类上下文中访问受保护的方法,即如果 $this 和 $this->instance 是相同的/$this->instance 的派生类型受保护的方法是可访问的。例如
class Foo {
protected $instance;
public function __construct(Foo $instance=null) {
$this->instance = $instance;
}
public function publicfn() {
if ( !is_null($this->instance)) {
call_user_func_array( array($this->instance, 'protectedfn'), array());
}
}
protected function protectedfn() {
echo 'Foo::protectedfn() invoked';
}
}
class Bar extends Foo {
protected function protectedfn() {
echo 'Bar::protectedfn() invoked';
}
}
$foo = new Foo(new Bar);
$foo->publicfn();
打印Bar::protectedfn() invoked
。但这不应该太难避免。