0

在 CakePHP文档的 CakeDC 评论插件中指出:

组件回调

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

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

它可以从控制器完美运行!:

公共函数 callback_commentsInitType() {

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

的新功能是什么让您可以做到这一点?我需要了解它是如何实现的,以便将来能够在我的组件上实施这种方法。

4

1 回答 1

2

在组件的代码中,如果您查看文件中的以下函数(从第 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::underscoreInflector::camelize

  1. Inflector::underscore将转换initTypeinit_type. 在这里查看文档。
  2. Inflector::camelize将进一步转换init_typeInitType. 在这里查看文档。

现在,如果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将被执行。

希望这可以帮助..

于 2013-10-15T09:22:27.473 回答