【问题标题】:cakePHP - how do I conditionally load a component into a controller?cakePHP - 如何有条件地将组件加载到控制器中?
【发布时间】:2010-08-03 09:08:49
【问题描述】:

我正在使用 http://www.webtechnick.com 的 cakephp 1.3 的 Facebook 插件。这是我目前拥有的:

class UsersController extends AppController {
    var $name = 'Users';
    var $components = array('Facebook.Connect');

    function beforeFilter {
        $this->set('facebookUser', $this->Connect->user());
    }
}

但我想有条件地加载 Facebook.Connect 组件,并在控制器中使用它 - 在 sudocode 中类似这样...

if ($thisIsTrue) {
    Load_the_component_and_make_it_ready_for_use;
    $this->set('facebookUser', $this->Connect->user());
}

我应该怎么做?

【问题讨论】:

标签: cakephp


【解决方案1】:

如果您在 CakePHP 2.0 中这样做,那真的很容易。我发现这个 SO 线程最初让我气馁,但它必须是 1.3 及更低版本的问题。例如:

public function beforeFilter(){
    parent::beforeFilter();
    $this->Paypal = $this->Components->load('Paypal');
}

这就是她写的全部内容。

【讨论】:

【解决方案2】:

由于组件是在加载控制器时初始化的,我不建议稍后再加载它。

就像 maggie 评论的那样,您可以加载组件 (http://book.cakephp.org/view/939/Loading-Components),但是您必须调用启动并初始化自己并将对象附加到您的控制器。

总而言之,让 $this->set... 有条件并让组件每次都加载可能会更容易。

【讨论】:

  • 每次都让组件加载的问题是,如果用户登录 Facebook,我无法将他们从我的站点中注销,因为该组件将 facebook 与 Auth 组件同步并记录用户回来。一个答案是先让用户退出 facebook,但这不是我想要的行为。我可能会弄乱该组件,但由于它是维护的,所以我真的不想这样做。所以我会尝试自己有条件地附加对象。干杯。
  • 啊,初始化方法是在组件内部定义的 - 所以我毕竟在搞乱组件......
  • 所以,事实证明这个 Facebook.Connect 组件已经有了一个初始化方法。我没有有条件地附加组件,而是修改了初始化方法,以根据我在从站点手动注销时设置的会话变量的状态,有条件地将用户与 Auth 同步(从而登录到站点)。
  • 仅供参考,这在 CakePHP 2.0 中并不难做到。在下面阅读我的答案
  • 链接中断404,以后发帖时请考虑在答案中添加相关代码:(
【解决方案3】:

除非我在这里遗漏了什么,否则你使用 App::import 来导入组件。

我听说您不想对模型执行此操作,因为幕后还有其他设置。但是组件应该没问题。

if( $condition ) {
 App::import( 'Component', 'MyComponent' );
 $this->MyComponent = new MyComponent();
 $this->MyComponent->method();
}

HTH, 特拉维斯

【讨论】:

  • 我试过上面的方法。复杂之处在于,该组件大量使用了 initialize() 回调,(我认为)该回调在控制器加载之前执行。因此,在加载用户控制器之前,组件会登录 Facebook,然后在控制器的 beforeFilter 中,您可以使用用户信息设置 viewVars。
  • 明白了。抱歉,我无法提供更多帮助,我对组件或将 Cake 绑定到 FB 应用程序都不熟悉。
【解决方案4】:

我知道这已经晚了,但是对于其他正在寻找如何执行此操作的人,您需要在调用父级的 __construct 之前将其添加到您的 __construct 中。

所以你会做这样的事情:

function __construct(){
  if($thisIsTrue){
    $this->components[] = 'Facebook.Connect'
  }
  parent::__construct();
}

您可以在您的个人控制器或 app_controller 中执行此操作,以便每个控制器都可以使用它。

我遇到的一个问题是因为它被调用得太早,很难为 if() 语句获取变量。在我的示例中,如果我在管理页面上,我只想要一个组件,而不是能够检查 $this->params,我必须检查来自 $_SERVER 的 URL。

我在这里找到了这个解决方案,但它说您必须在 app_controller 中执行此操作,但事实并非如此: Conditional Component Loading in CakePHP

【讨论】:

  • 是的,这很好用,除了在我使用的 Cake 2.1 中,我必须将构造函数参数传递给父级,例如...` function __construct($request = null, $response = null) { $this->components[] = 'RequestHandler';父::__construct($request, $response); }`
【解决方案5】:

在你的控制器中试试这个

var $components = array("Email", "Session", 'RequestHandler', 'Cookie');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 2017-11-14
    • 1970-01-01
    • 2017-07-27
    • 2016-12-01
    • 1970-01-01
    相关资源
    最近更新 更多