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

Posted

技术标签:

【中文标题】如何在 CakePhp 组件中调用回调?【英文标题】:How to call the callback in a CakePhp Component? 【发布时间】:2012-07-08 20:47:38 【问题描述】:

我使用的是 Cakephp 2.2,我有一个简单的控制器,名为 ProvidersController

<?php

class ProvidersController extends AppController 

    public $components = array('Session', 'Social');

    public $layout = false;         

    public function facebook() 
    $this->Social->auth('facebook', 'success', 'error');
    $this->render(false);
    

    public function google()
     $this->Social->auth('google', 'success', 'error');
     $this->render(false);
    

    private function success()

    

    private function error()

    



?>

还有这个名为SocialComponent的组件:

<?php

class SocialComponent extends Component 

    public function auth($provider, $success, $error)

    



?>

如您所见,我在控制器内部创建了 success() 和 error() 方法。现在我传递了这些名称,我想从组件中调用它们。

我只传回调的名字,如何从组件中调用?

谢谢!

【问题讨论】:

a) 它们是私有的——地球上没有任何类,除了这个相同的类可以实际调用它们 b) 你的组件不应该触发控制器方法。应该是相反的 【参考方案1】:

组件的重点是跨多个控制器的可重用性 - 如果您试图使其访问特定的控制器功能,您可能应该只使用控制器方法,而不是组件。

但是 - 您始终可以在组件中执行逻辑并传回数据(成功或错误时),然后检查控制器中的结果,并根据这些结果访问您想要的任何方法。

由于您的“成功”或“错误”逻辑在控制器中,我假设您不希望它出现在组件中...即每次使用组件时都会有所不同。在这种情况下,您真正​​希望组件做的只是执行逻辑并让您知道它是如何进行的(返回数据)。

//Controller
//..
public function facebook() 
    $results = $this->Social->auth('facebook', 'success', 'error');
    if($results['error']) $this->Social->error();
    $this->render(false);


private function success() 

private function error() 
//...


//Component
//...
public function auth($provider, $success, $error)
    $results = array();
    //do something
    $results['error'] = true;
    return $results;

//...

【讨论】:

虽然这是将成功/失败信息返回给控制器的有效解决方案,但该问题明确询问了回调模式中的细节。 哇,@pixelistik,在他将其标记为答案后,您否决了我?这似乎有点低,你不觉得吗?我阅读了这个问题,了解了他希望达到的目标,并做出了相应的回答。他是否认为我的回答有帮助取决于他——显然他做到了。我也相信我的回答会帮助 99% 试图从组件调用控制器方法的人,而实际上,他们最好按照我上面的建议去做。 我不是故意冒犯你的。我只是通过这个问题并解释了为什么我认为这不是答案的原因。而且我多次看到被赞成的问题与标记为正确的问题不同。 @pixelistik - 正如我所提到的,这个答案将帮助 99% 的人找到这个问题(它显然帮助了 OP)。这是一个可靠而有用的答案。在您更好地理解 *** 的目的之前,请不要对自己投反对票(在他人可能或可能不总是知道实现某事的最佳方法时帮助他人,并且可能不会在您眼中“完美”地表达他们的问题。)跨度> 【参考方案2】:

看一下 CakePHP 中的source code of the SecurityComponent,它和 blackHoleCallback 的情况是一样的。

他们使用辅助函数 SecurityComponent::_callback(),它使用 PHP 的 call_user_func_array()

protected function _callback(Controller $controller, $method, $params = array()) 
    if (is_callable(array($controller, $method))) 
        return call_user_func_array(array(&$controller, $method), empty($params) ? null : $params);
     else 
        return null;
    

您可以使用相同的模式将回调传递给您的组件。

【讨论】:

以上是关于如何在 CakePhp 组件中调用回调?的主要内容,如果未能解决你的问题,请参考以下文章

cakephp3 如何检查实体是不是是新插入的 afterSave 回调?

多次调用 Cakephp 回调函数

如何在 Cakephp 3 的 ajax 调用中定义 CSRF 令牌。此外,对于某些 ajax 请求,如何关闭 CSRF

CakePHP回调函数如何知道$ q是一个Query对象,哪个表执行查询?

如何在单元测试之前等待组件的挂载回调中的异步调用完成?

CakePHP 3 - beforeSave 回调在编辑时不起作用