2

这是前提:

我有很多类,我需要在调用任何类的任何方法之前执行操作,我的解决方案是让所有类扩展一个父类,该父类将定义一个 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 方法并指定我想要调用的实际方法,这样该方法就会被调用,但是在 call 方法(该类从我的父类继承)中,我可以执行我需要执行的操作在调用指定的方法之前退出。

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

我不确定我上面所说的是否有意义,我想检查一下我是否以错误的方式处理这个问题。

任何想法/想法将不胜感激。

谢谢!

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

4

4 回答 4

2

__call每当您尝试调用不存在的函数时,它会自动调用(如果已定义)。这就是为什么它是一种“神奇”的方法。在我看来,直接使用它而不是在它的预期上下文中使用它似乎很奇怪。在这里,您不妨将其命名为任何名称。

你绝对可以在这里__call发挥你的优势。尝试用下划线命名所有成员函数。所以,如果你以前有$this->print()你现在有$this->_print()。然后,在您的__call函数中,添加下划线并使用call_user_func_array(array($this,"_$name"), $params). 现在你可以正常调用你的函数了(好吧,没有下划线)。

不过,我不建议使用__callexcept 作为方便。从长远来看,最好只调用您想要直接运行的任何代码。

于 2010-11-04T02:32:32.357 回答
1

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

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

于 2010-11-04T02:24:30.230 回答
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);
}

再次感谢各位!

于 2010-11-04T03:26:57.280 回答
1

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

function __call($method, $args) {
    return call_user_func_array(array($this,$method),$args);
}
于 2015-07-06T09:53:24.447 回答