В попытке свободно связать мое приложение Phalcon с XenForo, я пытаюсь зарегистрировать метод из класса XenForo_Model_Thread с DI Phalcon следующим образом:
$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
магия реализована в вашем Phalcon\DI\Injectable
а также __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;
}
Других решений пока нет …