1

我需要能够调用一个方法而不必知道它是否是静态的。

例如,这不起作用,我希望它:

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

它不起作用的原因是因为我需要实例化类才能使实例变量起作用。但是我的构造函数不接受任何参数,所以我想要一个快速的方法来跳过这一步。

我怎样才能写这个,这样不管它是什么样的方法?

4

2 回答 2

2

可以用反射来做到这一点。假设你有这些变量:

$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 的用例,没有任何错误/警告/通知。

于 2012-08-28T18:09:02.770 回答
1

我认为存在设计问题 - 如果您需要实例方法,则需要实例,因此您可能需要访问该实例的属性。

如果您需要静态方法,则不需要引用任何实例,因此请使用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);

}
于 2012-08-28T18:07:57.450 回答