在组件的代码中,如果您查看此文件中的以下函数(从第 622 行开始):
/**
* Call action from commponent or overriden action from controller.
*
* @param string $method
* @param array $args
* @return mixed
*/
protected function _call($method, $args = array()) {
$methodName = 'callback_comments' . Inflector::camelize(Inflector::underscore($method));
$localMethodName = 'callback_' . $method;
if (method_exists($this->Controller, $methodName)) {
return call_user_func_array(array(&$this->Controller, $methodName), $args);
} elseif (method_exists($this, $localMethodName)) {
return call_user_func_array(array(&$this, $localMethodName), $args);
} else {
throw new BadMethodCallException();
}
}
您可以看到该变量$methodName
是用前缀定义的callback_comments
,然后在通过then方法$method
处理后将传递的附加到它。这些的工作如下:Inflector::underscore
Inflector::camelize
Inflector::underscore
将转换initType
为init_type
. 在这里查看文档。
Inflector::camelize
将进一步转换init_type
为InitType
. 在这里查看文档。
现在,如果initType
在参数中传递,那么$methodName
将是:
callback_comments
+ InitType
=callback_commentsInitType
在此之后,a$localMethodName
也正在生成。在我们的initType
示例中,它将是:
callback_
+ initType
=callback_initType
生成名称后,它将简单地搜索该方法是否存在于附加的控制器中,并使用call_user_func_array
函数通过传递它和带有对象的数组来执行它(在我们的例子中,控制器对象 ( &$this->Controller
) 或组件对象本身 ( &$this
) ) 包含方法和$methodName
作为第一个参数,然后$args
作为第二个参数。
如果在控制器中没有找到该函数,那么它将改为在组件中搜索$localMethodName
. 如果找到,则以相同的方式执行。
现在这一切的工作原理是,该_call
函数是用于调用组件所有内部函数的单个函数,因此它会首先检查该函数是否已在控制器中被覆盖,否则它将在组件本身中执行该函数.
您可以在此处检查组件的 beforeRender 函数,您将看到该initType
函数是如何调用的。在这种情况下,如果控制器包含一个名为 的函数callback_commentsInitType
,那么它将被执行。否则,组件callback_initType
将被执行。
希望这可以帮助..