Было бы очень хорошо иметь возможность доступа к загружаемым в bootstrap ресурсам из контроллеров приложения. Например, я хотел бы получить доступ к «DB» ресурсу из контроллера следующим образом $this->db;
Для этого напишем Action Helper, который будет загружать определенные ресурсы в контроллер приложения:
и инициализируем его в bootstrap:
Код выше, создаст ссылки на ресурсы: db, layout и navigation. Это значит, что теперь вы можете получить к ним прямой доступ из контроллеров.
Этото решение ведет к некоторому упрощению — теперь нет необходимости вытягивать bootstrap из объекта инициализации, а потом вытягивать ресурс.
Но, у этого решения есть несколько проблем: Откуда мы знаем, какие ресурсы были связаны с контроллером? Как мы можем это контролировать?
Отсюда, вытекает решение создать пул необходимых ресурсов для контроллера.
Новый Action Helper загрузки ресурсов теперь будет выглядеть так:
Вы все еще должны зарегистрировать его в bootstrap, но теперь уже без указанаия списка ресурсов:
Вместо этого, необходимый список ресурсовы вы теперь определяете в самом контроллере:
Это создает более четкое понимание какие ресурсы необходимы контроллеру, а также, каждый контроллер получает именно те ресурсы, которые он будет использовать.
Еще одно улучшение, которое мы можем добавить к загрузчику ресурсов — это, если зависимый ресурс не был найден, будет вызвано исключение:
Это дает нам лучшение понимание и отслеживания зависимых ресурсов. Ресурсы определяются объектом, который в них нуждается, а недостающие ресурсы будут вызывать исключение.
Одно потенциальное улучшение, которое можно сделать, это указание списока ресурсов загружаемых автоматически для каждого контроллера. Для реализации этого, необходимо будет объеденить список по умолчанию с ресурсами определенными в контроллрере. Эту задачу я оставляю для моих читателей.
Область Action Helpers является слабо исследованной ZF пользователями. Надеюсь, этот пост покажет как сильно Action Helpers могут автоматизировать повторяемые и общте задачи.
Эта статья является частичным перевод статьи Matthew Weier O'Phinney A Simple Resource Injector for ZF Action Controllers.
Для этого напишем Action Helper, который будет загружать определенные ресурсы в контроллер приложения:
class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;
public function __construct(array $resources = array())
{
$this->_resources = $resources;
}
public function preDispatch()
{
$bootstrap = $this->getBootstrap();
$controller = $this->getActionController();
foreach ($this->_resources as $name) {
if ($bootstrap->hasResource($name)) {
$controller->$name = $bootstrap->getResource($name);
}
}
}
public function getBootstrap()
{
return $this->getFrontController()->getParam('bootstrap');
}
}
* This source code was highlighted with Source Code Highlighter.
и инициализируем его в bootstrap:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initResourceInjector()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_ResourceInjector(array(
'db',
'layout',
'navigation',
));
);
}
}
* This source code was highlighted with Source Code Highlighter.
Код выше, создаст ссылки на ресурсы: db, layout и navigation. Это значит, что теперь вы можете получить к ним прямой доступ из контроллеров.
class FooController extends Zend_Controller_Action
{
public function barAction()
{
$this->layout->disableLayout();
$model = $this->getModel();
$model->setDbAdapter($this->db);
$this->view->assign(
'model' => $this->model,
'navigation' => $this->navigation,
);
}
// ...
}
* This source code was highlighted with Source Code Highlighter.
Этото решение ведет к некоторому упрощению — теперь нет необходимости вытягивать bootstrap из объекта инициализации, а потом вытягивать ресурс.
Но, у этого решения есть несколько проблем: Откуда мы знаем, какие ресурсы были связаны с контроллером? Как мы можем это контролировать?
Отсюда, вытекает решение создать пул необходимых ресурсов для контроллера.
Новый Action Helper загрузки ресурсов теперь будет выглядеть так:
class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;
public function preDispatch()
{
$bootstrap = $this->getBootstrap();
$controller = $this->getActionController();
if (!isset($controller->dependencies)
|| !is_array($controller->dependencies)
) {
return;
}
foreach ($controller->dependencies as $name) {
if ($bootstrap->hasResource($name)) {
$controller->$name = $bootstrap->getResource($name);
}
}
}
public function getBootstrap()
{
return $this->getFrontController()->getParam('bootstrap');
}
}
* This source code was highlighted with Source Code Highlighter.
Вы все еще должны зарегистрировать его в bootstrap, но теперь уже без указанаия списка ресурсов:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initResourceInjector()
{
Zend_Controller_Action_HelperBroker::addHelper(
new My_ResourceInjector();
);
}
}
* This source code was highlighted with Source Code Highlighter.
Вместо этого, необходимый список ресурсовы вы теперь определяете в самом контроллере:
class FooController extends Zend_Controller_Action
{
public $dependencies = array(
'db',
'layout',
'navigation',
);
public function barAction()
{
$this->layout->disableLayout();
$model = $this->getModel();
$model->setDbAdapter($this->db);
$this->view->assign(
'model' => $this->model,
'navigation' => $this->navigation,
);
}
// ...
}
* This source code was highlighted with Source Code Highlighter.
Это создает более четкое понимание какие ресурсы необходимы контроллеру, а также, каждый контроллер получает именно те ресурсы, которые он будет использовать.
Еще одно улучшение, которое мы можем добавить к загрузчику ресурсов — это, если зависимый ресурс не был найден, будет вызвано исключение:
class My_ResourceInjector extends Zend_Controller_Action_Helper_Abstract
{
protected $_resources;
public function preDispatch()
{
$bootstrap = $this->getBootstrap();
$controller = $this->getActionController();
if (!isset($controller->dependencies)
|| !is_array($controller->dependencies)
) {
return;
}
foreach ($controller->dependencies as $name) {
if (!$bootstrap->hasResource($name)) {
throw new DomainException("Unable to find dependency by name '$name'");
}
$controller->$name = $bootstrap->getResource($name);
}
}
public function getBootstrap()
{
return $this->getFrontController()->getParam('bootstrap');
}
}
* This source code was highlighted with Source Code Highlighter.
Это дает нам лучшение понимание и отслеживания зависимых ресурсов. Ресурсы определяются объектом, который в них нуждается, а недостающие ресурсы будут вызывать исключение.
Одно потенциальное улучшение, которое можно сделать, это указание списока ресурсов загружаемых автоматически для каждого контроллера. Для реализации этого, необходимо будет объеденить список по умолчанию с ресурсами определенными в контроллрере. Эту задачу я оставляю для моих читателей.
Область Action Helpers является слабо исследованной ZF пользователями. Надеюсь, этот пост покажет как сильно Action Helpers могут автоматизировать повторяемые и общте задачи.
Эта статья является частичным перевод статьи Matthew Weier O'Phinney A Simple Resource Injector for ZF Action Controllers.