【问题标题】:How to Optimize Models in Zend Framework?Zend 框架中如何优化模型?
【发布时间】:2012-02-21 15:43:53
【问题描述】:

我需要找出在 Zend Framework 中有效利用模型的最佳实践。

目前,我有扩展 Zend_Db_Table_Abstract 的类,它们处理我对每个类各自表的查询。

当我需要从控制器访问其中的 5 个表时,我发现自己为每个特定的 Zend_Db_Table 对象创建了 5 个新实例。这真是无效。

我考虑过实现工厂模式来创建新实例(或提供现有的静态副本),但不确定。这是最好的方法吗?

在不消耗过多资源的情况下处理模型的正确方法是什么?延迟加载应该在这里发挥作用吗?

[编辑] 例如,我有一个类用于处理从原始搜索查询中获取有关位置的详细信息,并且需要这些对象来解析查询:

// Initialize database object
$this->dbLocations = new Model_Locations;
$this->dbStates = new Model_States;
$this->dbZipcodes = new Model_Zipcodes;
$this->dbLookup = new Model_Lookup;

在另一个类中,我可能需要再次访问这些模型,所以我重复上面的代码。本质上是重新初始化可能为静态/单例的对象。

【问题讨论】:

  • 你的问题是相当的工资,你能展示一个代码示例,你实际上创建了 5 个表类的实例并描述你需要它们做什么。
  • 我理解您的担忧,但并没有真正关注。我会说,在 OOP 中创建一个类的多个实例,尤其是一个抽象类是一件既定的事情。质疑这个表模型对我来说有点像质疑 OOP 或继承。
  • 在基本层面上,这种方法的使用是可以接受的。我有一个自定义的“处理程序”,因为没有更好的词“,它接受一个查询对象,解析其中的属性并将其传递给一个位置处理程序,该处理程序获取该查询的所有位置数据,然后将其传递给一个潮汐数据处理程序以及天气数据处理程序。在此过程的许多阶段,我需要访问各种表并最终从各种类中启动这些对象。有关更多信息,请参阅:stackoverflow.com/questions/9116838/…
  • 好吧,如果您担心创建太多对象,您可以随意使用$db->query('SELECT * FROM tide'); 而不是 Zend_Db_Table。这样你就只剩下一个对象了。

标签: php database oop zend-framework


【解决方案1】:

我倾向于像你一样在 DbTable 工作。当我需要在单个操作中查询多个表以在 dbTable 之上创建另一层模型时,我发现它很有效。类似于服务或领域层。这样我只需要调用一个模型,但我仍然拥有我需要的功能。

这是一个简单的示例,它最终可能与 5 个 DbTable 类以及很可能与几个 Row 类交互:

<?php

class Application_Model_TrackInfo
{


    protected $_track;
    protected $_bidLocation;
    protected $_weekend;
    protected $_shift;
    protected $_station;

    public function __construct() {
        //assign DbTable models to properties for convience
        $this->_track = new Application_Model_DbTable_Track();

    }

    /**
     *
     * @param type $trackId
     * @return type object
     */
    public function getByTrackId($trackId) {

        $trackData = $this->_track->fetchRow($trackId);
        //getAllInfo() Application_Model_Row_TRack
        $result = $trackData->getAllInfo();
        //returns std object reflecting data from 3 DbTable classes
        return $result;
    }

    /**
     *Get Station from trackid through bidlocationid
     *
     * @param type $trackId
     * @return type object
     */
    public function getStation($trackId){

        $data = $this->_track->fetchRow($trackId);
        //This a Application_Model_Row_Track method
        $result= $data->getStationFromBidLocation();

        return $result;
    }

} 

我希望这会有所帮助。

[编辑] 自从我写了这个答案以来,我已经了解了域模型和数据映射器的好处。哇,我的应用程序有什么不同。不是灵丹妙药,而是巨大的进步。
感谢
Alejandro Gervasio 在PHPMaster.com
Rob Allen Akrabat.com

Pádraic Brady Surviving The Deepend

感谢他们对理解这种模式的所有帮助。

【讨论】:

  • 每次使用 Application_Model_TrackInfo 类时,它都会解决我遇到的问题。创建可能会或可能不会使用的 dbTable 对象,然后将其删除,并且您下次使用它会再次创建它。这些 dbTable 连接应该在工厂范例中生成,还是多个并发实例是必须处理的可接受开销?
  • @cilosis 听起来你最好看看缓存策略,这样你就可以最小化你的 Db 查询。 ORM(具有一些数据持久性)解决方案也可能是合适的。
【解决方案2】:

您似乎处于一个需要有效数据管理的位置,该管理具有当前 Zend 框架不具备的功能。 Zend 没有用于处理任何类型数据库的内置引擎,它只是有一个包装类来帮助您编写查询。

您需要的是一个对象关系模型 (ORM),它是专业框架中必不可少的。据我了解,ORM 本身就是一个框架,它具有模式和严格定义的“做事”方式,支持延迟加载(它充分利用了它)并最大限度地优化您的查询。当您使用 ORM 时,您甚至不编写 SQL,而是需要更改对数据存储的解释,您需要忘记表并专注于对象。例如,在 Doctrine 中,每个类型(表)都由一个类指定,每个记录(行)作为一个类实例,您可以在其中访问不同的方法和属性。它支持事件监听器和疯狂的级联关系。

删除记录时不再需要从相关表中提取行(它是自动的),不再需要编写复杂而混乱的脚本来确保文件系统同步,您可以随时迁移到几乎任何数据库引擎(mysql, postgresql, simplesql..) 等等..

我一直在将 Doctrine 2 与 Symfony 2 框架结合使用,我不得不说我不会再回到 Zend 做任何事情。是的,它既复杂又沉重,但确实是最终的解决方案。当您需要管理数以百万计的记录的数百个表时,您就会看到不同之处。

所以,最后的总结: ORM 是你需要的,有很多解决方案,我知道有两个非常好:Doctrine 1 或 2 和 Propel。

P.S.:ORM 是您系统的一个独立部分,因此您实际上不需要使用特定的框架,Zend 可以配置为与 Doctrine 完美配合 :)

【讨论】:

  • Zend_Db 本身就是 ORM 模式的实现。您的回答并没有解决OP的真正问题,它只是告诉他根据您的个人意见更换工具。您的第一段完全错误,这表明您在谈论您实际上并不知道的事情。
  • 我没有写任何内容,因为目前问题中没有足够的信息来写答案。
  • 它可能会保持这种状态,至少我的解决方案是可行的,即使不完全符合 OP 的要求。
  • 我目前不需要 ORM 的开销。但是,对于 SO 的未来研究,这个答案和 cmets 可能会提供一些有用的见解。
猜你喜欢
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 1970-01-01
  • 2010-09-22
  • 1970-01-01
相关资源
最近更新 更多