我需要能够调用一个方法,而不必知道它是否是静态的。
例如,这不起作用,我希望它:
class Groups {
public function fetchAll($arg1, $arg2){
return $this->otherFunction();
}
public static function alsoFetchAll($arg1, $arg2){}
}
$arguments = array('one', 'two');
$result = call_user_func_array(array('Groups', 'fetchAll'), $arguments);
$result = call_user_func_array(array('Groups', 'alsoFetchAll'), $arguments);
我得到了一个变量实例的错误:
Fatal error: Using $this when not in object context
它不起作用的原因是,我需要实例化类才能使实例变量起作用。但是我的构造函数不接受任何参数,所以我想用一种快速的方法跳过这一步。
我怎么能写这篇文章,这样它就不在乎是什么样的方法了?
您可以使用反射来执行此操作。假设你有这些变量:
$class = 'Groups';
$params = array(1, 'two');
然后您可以创建该类的一个新实例:
$ref = new ReflectionClass( $class);
$instance = $ref->newInstance();
并以相同的方式调用这两个方法,检查它们是否是静态的以确保完整性:
$method = $ref->getMethod( 'fetchAll');
$method->invokeArgs( ($method->isStatic() ? null : $instance), $params);
$method = $ref->getMethod( 'alsoFetchAll');
$method->invokeArgs( ($method->isStatic() ? null : $instance), $params);
然而,你不需要确保它们是静态的,你可以很容易地做到这一点,无论方法是否是静态的:
$ref->getMethod( 'fetchAll')->invokeArgs( $instance, $params);
$ref->getMethod( 'alsoFetchAll')->invokeArgs( $instance, $params);
你可以在这个演示中看到它的工作。
编辑:这里有一个演示,展示了它与OP的用例一起工作,没有任何错误/警告/通知。
我认为存在一个设计问题-如果您需要一个实例方法,则需要一个实例,因此您可能需要访问该实例的属性。
如果您需要一个静态方法,则不需要引用任何实例,所以使用call_user_func_array
。当您处理存储库方法时,您可以使它们成为静态的,而不会有任何问题——无论如何,如果您需要一个解决方案:
function callMethod($class, $method, $arguments)
{
// if there is no such method, return
$info = new ReflectionClass($class);
if(!$info -> hasMethod($method))
return false;
// let's find if desired method is static - create a temporary instance in case
foreach($info -> getMethods(ReflectionMethod::IS_STATIC) as $method)
{
if($method['name'] == $method)
{
$class = $info -> newInstance;
break;
}
}
return call_user_func_array(array($class, $method), $arguments);
}