Инициирование объектов в Zend Framework? - PullRequest
1 голос
/ 12 января 2012

Как исключить запись $object = new Application_Model_Database() на каждом контроллере?

Например, для контроллера статей я должен ввести $articles = new Application_Model_Articles() для каждого контроллера. Должен ли я поместить его под контроллером просмотра, помощниками действий или любым другим способом?

Ответы [ 5 ]

2 голосов
/ 12 января 2012

Ваш вопрос почти звучит как вопрос о наилучшей практике ООП, а не как вопрос, специфичный для Zend Framework. Независимо от того, использую ли я фреймворк и независимо от того, какую фреймворк я выбрал, я основываю, когда и где я создаю новые объекты на тестируемости, сколько раз мне нужно написать $object = new My_Random_Object();.

Говоря конкретно о Zend Framework: объекты, которые я собираюсь использовать везде или почти везде, создаются в Bootstrap.php . Эти объекты обычно включают в себя адаптер базы данных, регистратор, объект просмотра и любые плагины, которые я мог бы использовать. Чтобы получить к ним доступ через приложение, я создам частные свойства в соответствующих контроллерах и назначу объекты этим свойствам в методе контроллера init ().

class ExampleController extends Zend_Controller_Action
{

    public function init()
    {
        $bootstrap = $this->getInvokeArg('bootstrap');
        $this->_db = $bootstrap->getResource('db');
        $this->_log = $bootstrap->getResource('log');
        // and so on, and so forth
    }

}

В идеале, модели, сервисы, daos и т. Д. Будут относительно тесно сгруппированы по контроллеру и действиям. По моему опыту, и это вообще говоря, если у меня одна и та же модель или класс обслуживания, обнаруживаемый на всех контроллерах в моем приложении, у меня возникла организационная проблема. При этом любая модель, которая появляется только в одном действии, создается в этом действии. Если он выполняет действия в контроллере, он создается в методе init () и присваивается свойству. Если он отображается на нескольких контроллерах, он создается в моем Bootstrap.php.

(В идеале все создается в Bootstrap.php, так что вы можете поменять этот загрузчик для тестирования. К сожалению, я не всегда так делаю, и чаще всего я использую принципы, изложенные выше.)

1 голос
/ 12 января 2012

Другой возможностью является использование контейнера для инъекций зависимости, такого как компонент Symfony DI .Он заботится о создании ваших объектов, и вы получаете некоторые дополнительные преимущества:

  • Разделение интересов .У вас есть компонент, предназначенный для создания дерева объектов.
  • Более легкая тестируемость объектов.
  • Наконец, что не менее важно, преимущества в производительности, предоставляемые отложенной реализацией (объекты создаются только по запросудля них).Таким образом, если какой-то объект не используется конкретным контроллером, обслуживающим ваш запрос, он не создается).

Это немного более трудоемко, чем приведенные выше решения, но гораздо более гибко, если вам нужно поддерживать ипродлите вашу заявку в будущем.

Надеюсь, это поможет,

1 голос
/ 12 января 2012

Если вы хотите использовать модели в контроллерах, вы должны называть это ... в любом случае, здесь есть несколько ярлыков

1.Вы можете инициализировать его в разделе инициализации вашего контроллера, как

public function init(){
   $this->object = new Application_Model_Database();
}

Так что this->object доступно во всех действиях этого конкретного контроллера

2. Используйте Zend_registry, как предложено в ответе выше

1 голос
/ 12 января 2012

Ну, тебе это действительно нужно в каждом контроллере?Потому что это в значительной степени дизайн.Вы реализуете модели, когда они вам нужны.На самом деле это не так уж много кода.

Теперь, если его использовать в действиях контроллера, вы всегда можете:

class MyController extends Zend_Controllers{
     $protected $_articleModel;

...

и в своем конструкторе.или функция __init () инициализирует его, чтобы вы могли использовать его в каждом действии через $this->_articleModel

Если вы ДЕЙСТВИТЕЛЬНО хотите, чтобы это было везде в вашем приложении, просто инициализируйте его в своем загрузчике и сохраните в реестре.

public function __initModels(){
  $articles = new Application_Model_Articles() 
  Zend_Registry::set('articles', $articles );
}

И доступ к нему в ваших контроллерах, например, так:

Zend_Registry::get('articles')->fetchAll();

Но тогда вы по-прежнему пишете пару символов.

Надеюсь, эта помощь!

0 голосов
/ 12 января 2012

Если вы используете этот объект для отображения данных в вашем представлении и используете свой контроллер, чтобы получить данные и назначить их вашему представлению, например, так:

//someControllerAction
$object = new Application_Model_Articles();
$object->fetchAll();
//assign to view
$this->view->articles = $object;

Возможно, вам лучше создать помощника вида, похожего на:

//Articles.php put in /application/views/helpers  
class Zend_View_Helper_Articles extends Zend_View_Helper_Abstract {

public function Articles() {

$articles = new Application_Model_Articles();
$articles->fetchAll();
//return rowset object
return $articles;

Тогда, на ваш взгляд (phtml) вы можете сделать что-то вроде:

//someView.phmtl
<?php $articles = $this->Articles(); ?>
<h1><?php echo $this->escape($articles->title); ?></h1>
<p><?php echo $this->escape($articles->body); ?></p>

Создание помощника вида позволяет полностью обойти контроллер, если вам просто нужно отобразить данные из модели. Это очень простой пример, который можно использовать с частичными и частичными циклами.
REF: Справочник по ZF Помощник для пользовательского просмотра
Справочник по частичному виду ZF

...