1

$object = new Application_Model_Database()我怎样才能消除在每个控制器中写入?

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

4

5 回答 5

2

您的问题几乎听起来像是一个 OOP 最佳实践问题,而不是 Zend 框架特定的问题。不管我是否使用框架,也不管我选择什么框架,我创建新对象的时间和地点都是基于我必须编写多少次可测试性$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 中创建,因此您可以出于测试目的换掉该引导程序。遗憾的是,我并不总是这样做,而且我最常使用我上面概述的原则。)

于 2012-01-12T05:41:22.113 回答
1

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

  • 关注点分离。您有一个专门用于创建对象树的组件。
  • 对象的可测试性更容易。
  • 最后但并非最不重要的一点是延迟实例化带来的性能优势(对象仅在您请求时创建)。因此,如果为您的请求提供服务的特定控制器未使用某些对象,则它不会被实例化)。

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

希望有帮助,

于 2012-01-12T09:14:18.253 回答
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();

但是你仍然在写几个字符。

希望这有帮助!

于 2012-01-12T04:45:39.283 回答
1

如果你想在控制器中使用模型,你必须调用它......无论如何,这里有一些快捷方式

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

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

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

2.按照上述答案中的建议使用 Zend_registry

于 2012-01-12T05:34:16.467 回答
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 参考自定义视图助手
ZF 局部视图助手参考

于 2012-01-12T09:48:54.850 回答