题
这是前提:
我有很多课程需要在任何类别的任何方法中都需要执行操作,我的解决方案是让所有类都扩展了一个父类,该类将定义一个呼叫()函数,该函数看起来像:
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);
}
然后只需调用呼叫方法,并指定我要调用的实际方法,这样该方法将被调用,但是在呼叫方法中(类从父母班级继承),我可以执行我需要进行的操作在调用指定方法之前出来。
这需要能够支持可能是数组或字符串的参数,因此任何涉及爆炸一系列参数的事物都不会起作用(因为这将假设所有参数都是字符串)。
我不确定我上面的内容是否有意义,我想检查一下我是否以错误的方式进行此操作。
任何想法/想法都将不胜感激。
谢谢!
PS:我应该注意,我对上述情况的描述听起来像是子类扩展父母仅仅为此目的的原因,实际上有更多原因(我的父班级扩展了zend_db_table_abstract,我的数据库模型扩展了父母) 。
解决方案
__call
每当您尝试调用不存在的函数时,就会自动称为自动定义。这就是为什么它是一种“魔术”方法。对我来说,直接使用它,而不是在其预期的上下文中使用它似乎很奇怪。在这里,您不妨将其命名。
你 可以 绝对使用 __call
为了您的优势。尝试在他们面前命名所有成员功能。所以,如果你以前 $this->print()
你现在有 $this->_print()
. 。然后,在你的 __call
功能,添加下划线并使用 call_user_func_array(array($this,"_$name"), $params)
. 。现在,您可以正常调用您的功能(嗯,没有下划线)。
不过,我不建议使用 __call
除了方便。长期,最好只调用您要直接运行的任何代码。
其他提示
我更好/更清洁的替代方法可能是设置事件和听力系统,例如 学说事件系统. 。 (该代码实际上来自普通库,而不是ORM部分。)但是您需要所有的方法来派遣事件。
我尝试避免尽可能多地使用__ 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 call_user_func_array(array($this,$method),$params);
}
再次感谢!
您可以直接从__call参数获取方法参数:
function __call($method, $args) {
return call_user_func_array(array($this,$method),$args);
}