为了将我的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
不是,这就是它应该的样子。你可以用下面的小扭曲来扩展Injectable
或Controller
,这就可以了。
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;
}