这是前提:

我有很多课程需要在任何类别的任何方法中都需要执行操作,我的解决方案是让所有类都扩展了一个父类,该类将定义一个呼叫()函数,该函数看起来像:

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);
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top