在Zend Framework中启动对象?

时间:2012-01-12 04:13:25

标签: zend-framework zend-framework-modules

如何消除在每个控制器中写入$object = new Application_Model_Database()

例如,对于文章控制器,我必须为每个控制器键入$articles = new Application_Model_Articles()。我应该把它放在观众控制器,动作助手或任何其他方式下吗?

5 个答案:

答案 0 :(得分:2)

您的问题几乎听起来像是一个OOP最佳实践问题,而不是Zend Framework特定问题。无论我是否使用框架,无论我选择何种框架,我都会根据可测试性创建新对象的时间和地点,我必须写多少次$object = new My_Random_Object();

专门针对Zend框架:我将在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 :(得分:1)

你真的需要每个控制器吗?因为这几乎是设计的。您可以在需要时实施模型。真的没有那么多代码。

现在,如果要在控制器的操作中使用它,您可以随时:

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();

但是你还在写几个角色。

希望这有帮助!

答案 2 :(得分:1)

如果你想在控制器中使用模型,你必须调用它。但是这里有一些快捷方式

1.您可以在控制器的init部分初始化它,如

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

这样this->object在该特定控制器的所有操作中都可用

2.按照上述答案

的建议使用Zend_registry

答案 3 :(得分:1)

另一种可能性是使用依赖注入容器,例如Symfony DI component。它负责实例化您的对象,并获得一些额外的好处:

  • Separation of concerns。您有一个专门用于创建对象树的组件。
  • 更容易测试对象。<​​/ li>
  • 最后,但并非最不重要的是,懒惰实例化给出的性能优势(对象只在您要求时才创建)。因此,如果某个对象没有被服务于您请求的特定控制器使用,则它不会被实例化。

它比上述解决方案更费力,但如果您将来需要维护和扩展应用程序,则会更加灵活。

希望有所帮助,

答案 4 :(得分:0)

如果您使用此对象只是在视图中显示数据,并且正在使用控制器获取数据并将其分配给您的视图,如下所示:

//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>
如果您只需要显示模型中的数据,那么构建视图助手可以让您完全绕过控制器。这是一个非常简单的示例,可以与partials和partialLoops一起使用 REF:ZF reference Custom View Helper
   ZF partial view helper reference