Вы можете достичь того же, не используя классы 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
Возможно, вы захотите посмотреть, если это всегда было так. Там, например, запись - 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
. Но этого не должно быть слишком трудно избежать.