动态函数参数和使用__call

时间:2010-11-04 02:17:18

标签: php php-5.3

这是前提:

我有许多类需要在调用任何类的任何方法之前执行操作,我的解决方案是让所有类扩展一个父类,它将定义一个call()函数,它看起来像:

public function call($method){
    //do the something I need to do before method calls
    $params = func_get_args();
    //remove the $method param from the $params array
    unset($params[0]);
    return $this->__call($method,$params);
}

然后简单地调用call方法并指定我想要调用的实际方法,这样方法就会被调用,但是在调用方法中(类继承自我的父类)我可以执行动作I需要在调用指定方法之前执行。

这需要能够支持可能是数组或字符串的参数,因此任何涉及破坏参数数组的内容都不起作用(因为这会假设所有参数都是字符串)。

我不确定我上面的内容是否合理,我想检查一下我是否会以错误的方式进行此操作。

非常感谢任何想法/想法。

谢谢!

PS:我应该注意到我对上述情况的描述使得听起来像子类扩展父类的原因仅仅是为了这个目的,实际上有更多的原因(我的父类扩展了Zend_Db_Table_Abstract并且我的数据库模型扩展了父母)。

4 个答案:

答案 0 :(得分:2)

每当您尝试调用不存在的函数时,如果已定义

__call,则会自动调用它。这就是为什么它是一种“神奇”的方法。我直接使用它似乎很奇怪,而不是在预期的上下文中使用它。在这里,您可能已将其命名为任何内容。

尝试使用下划线命名所有成员函数。所以,如果您之前有__call,那么您现在拥有$this->print()。然后,在$this->_print()函数中,添加下划线并使用__call调用该函数。现在你可以正常调用你的函数了(好吧,没有下划线)。

尽管如此,除了方便之外,我不会建议使用call_user_func_array(array($this,"_$name"), $params)。长期最好只调用任何想直接运行的代码。

答案 1 :(得分:1)

我更好/更清洁的替代方案可能是设置一个事件和听力系统,如Doctrine Events System。 (该代码实际上来自Common库,而不是ORM部分。)但是您需要所有方法来分派事件。

我尽量避免使用__call,因为它会让你的代码更难理解和维护,尽管我觉得在插件系统中使用它很好。

答案 2 :(得分:1)

感谢您的建议,我是一种咆哮错误的树,但这是我提出的解决方案:

public function call($method){
    //do the something I need to do before method calls
    $params = func_get_args();
    //remove the $method param from the $params array
    unset($params[0]);
    return call_user_func_array(array($this,$method),$params);
}

再次感谢你们!

答案 3 :(得分:1)

您可以直接从__call参数中获取方法参数:

function __call($method, $args) {
    return call_user_func_array(array($this,$method),$args);
}