这个回调如何对 cakePHP 组件起作用?

Posted

技术标签:

【中文标题】这个回调如何对 cakePHP 组件起作用?【英文标题】:How does this callback works for a cakePHP component? 【发布时间】:2013-10-22 14:32:06 【问题描述】:

在用于 Cakephp 的 CakeDC cmets 插件中 documentation 声明:

组件回调

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

callback_add 将在控制器中命名为 callback_cmetsAdd, callback_fetchData 将命名为 callback_cmetsFetchData 在 控制器。 ...

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

公共函数 callback_cmetsInitType()

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

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

【问题讨论】:

github.com/CakeDC/comments/blob/… 为什么要覆盖组件函数如果你想覆盖另一个类中的函数,那么你应该将功能实现为插件。 @VikashPathak 主要是我需要了解 CakeDC 插件中发生了什么! 【参考方案1】:

在组件的代码中,如果你看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 定义的,然后在经过Inflector::underscoreInflector::camelize 方法处理后,将传递的$method 附加到它上面。它们的工作如下:

    Inflector::underscore 会将initType 转换为init_type。检查文档here。 Inflector::camelize 将进一步将init_type 转换为InitType。检查文档here。

现在,如果在参数中传递了initType,那么$methodName 将是:

callback_comments + InitType = callback_commentsInitType

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

callback_ + initType = callback_initType

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

如果在控制器中没有找到该函数,那么它将改为在带有$localMethodName 的组件中搜索。如果找到,则以同样的方式执行。

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

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

希望这会有所帮助..

【讨论】:

以上是关于这个回调如何对 cakePHP 组件起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CakePhp 组件中调用回调?

布局中的 CakePHP 动态菜单内容

cakephp函数更新一行不起作用

Popover 组件 - onExited 回调不起作用,材质 ui

从子组件更新父状态在 reactjs 中不起作用

组件内导航防护回调不起作用:Nuxt JS 和`beforeRouteEnter`