如何使用 Phalcon 的 DI 注册类方法?



为了将我的Phalcon应用程序与XenForo松散耦合,我试图将XenForo_Model_Thread类中的一个方法注册为Phalcon的DI,如下所示:

$di->set('forum', function () {
    XenForo_Autoloader::getInstance()->setupAutoloader('../forums/library');
    XenForo_Application::initialize('../forums/library', '../forums', true, array('resetOutputBuffering' => false));
    XenForo_Session::startPublicSession();
    $model = XenForo_Model::create('XenForo_Model_Thread');
    $callback = function ($id) use ($model) {
        return $model->getThreadsInForum($id);
    };
    return $callback;
});

我希望能够从我的控制器调用这个方法,如下所示:

$forum = $this->forum(2);

显然这行不通。

但这是有效的:

$di->set('forum', function () {
    XenForo_Autoloader::getInstance()->setupAutoloader('../forums/library');
    XenForo_Application::initialize('../forums/library', '../forums', true, array('resetOutputBuffering' => false));
    XenForo_Session::startPublicSession();
    $model = XenForo_Model::create('XenForo_Model_Thread');
    return array($model, 'getThreadsInForum');
});

然后我可以从控制器上做到这一点:

$forum = call_user_func($this->forum, 2);

不过,我不喜欢用这种奇怪的东西把我的代码弄得一团糟。有更好的方法吗?

你是一个严重的PHP离经叛道者,我不会在枪口下建议你这样做,但这是一个有趣的问题。如果您也这样做,但首先得到回调(而不是直接调用它),那么一切都应该按预期进行。

$di->set('forum', function () {
    XenForo_Autoloader::getInstance()->setupAutoloader('../forums/library');
    XenForo_Application::initialize('../forums/library', '../forums', true, array('resetOutputBuffering' => false));
    XenForo_Session::startPublicSession();
    $model = XenForo_Model::create('XenForo_Model_Thread');
    $callback = function ($id) use ($model) {
        return $model->getThreadsInForum($id);
    };
    return $callback;
});
$callback = $this->forum;
$forum = $callback(2);

为什么?因为__get魔术是在你的PhalconDIInjectable中实现的,而__call不是,这就是它应该的样子。你可以用下面的小扭曲来扩展InjectableController,这就可以了。

function __call($name, $arguments)
{
    if (is_callable($callback = $this->$name)){
        return call_user_func_array($callback, $arguments);
    }
    // Or throw a bad method call exception…
    return null;
}

最新更新