这个回调如何用于cakePHP组件?

时间:2013-10-14 22:16:00

标签: php cakephp callback components

CakeDC的CakeDC评论插件documentation表示:

  

组件回调

     

可以覆盖或扩展最多注释组件   控制器中的方法。为此,我们需要创建方法   前缀callback_comments示例:

     

callback_add将在控制器中命名为callback_commentsAdd,   callback_fetchData将命名为callback_commentsFetchData   控制器。 ...

它完美地在控制器上运行!:

  

public function callback_commentsInitType(){

    return 'flat'; // threaded, tree and flat supported
}

我想知道允许你这样做的新功能是什么?我需要了解如何能够在未来的组件上实现这种方法。

1 个答案:

答案 0 :(得分:2)

在组件的代码中,如果查看this文件中的以下函数(从第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,然后在$method处理之后将Inflector::underscore附加到其中,然后{ {1}}方法。这些工作如下:

  1. Inflector::camelize会将Inflector::underscore转换为initType。检查文档here
  2. init_type会进一步将Inflector::camelize转换为init_type。检查文档here
  3. 现在,如果在参数中传递InitType,那么initType将是:

    $methodName + callback_comments = InitType

    此后,还会生成callback_commentsInitType。在我们的$localMethodName示例中,它将是:

    initType + callback_ = initType

    在生成名称之后,它将简单地搜索附加控制器中是否存在该方法,并使用callback_initType函数执行它,方法是将其传递给对象(在我们的例子中是控制器对象) call_user_func_array)或组件对象本身(&$this->Controller))包含方法,&$this作为第一个参数,然后$methodName作为第二个参数。

    如果在控制器中找不到该功能,则它将使用$args搜索组件。如果找到了,那么它将以相同的方式执行。

    现在所有这些工作原理是$localMethodName函数是用于调用组件的所有内部函数的单个函数,因此它将首先检查函数是否已在控制器中被覆盖,否则它将在组件本身中执行该功能。

    您可以检查组件的beforeRender函数here,然后您将看到如何调用_call函数。在这种情况下,如果控制器包含名为initType的函数,那么它将被执行。否则,将执行组件callback_commentsInitType

    希望这会有所帮助..