Zend:两个对象,一行

时间:2009-08-11 18:16:06

标签: php zend-framework zend-db zend-db-table

我最近开始使用Zend Framework(1.8.4),提供管理工具来查看购物车网站的订单。

我想要做的是从单个数据库结果行有效地创建多个模型(Zend_Db_Table_Row_Abstract)对象。

关系很简单:    订单有一个客户(外键order_custid=customer.cust_id);    客户有很多订单。

加载订单很简单。使用此处记录的方法:

Modeling objects with multiple table relationships in Zend Framework

......然后我可以抓住每个客户。


    foreach ($orderList as $o)
    {
        cust = $o->findParentRow('Customers');
        print_r ($cust); // works as expected.
    }

但是当你加载一长串订单时 - 比方说40个或更多,一个页面 - 这很慢。

接下来我尝试了JOIN:


    $custTable = new Customers();
    $orderTable = new Orders();
    $orderQuery = $orderTable->select()
        ->setIntegrityCheck(false) // allows joins
        ->from($orderTable)
        ->join('customers', 'cust_id=order_custid')
        ->where("order_status=?", 1); //incoming orders only.
    $orders = $orderTable->fetchAll($orderQuery);

这给了我一个订单对象数组。 print_r($orders)显示每个列都包含我希望在受保护成员中使用原始字段名称order_ *和cust _ *的列列表。

但是如何从我在每个Order对象中找到的cust_ *字段创建一个Customer对象?


foreach ($orders as $o) {
    $cols = $o->toArray();
    print_r ($cols); // looks good, has cust_* fields...

    $cust = new Customer(array( 'table' => 'Customer', 'data' => $cols ) );
    // fails - $cust->id, $cust->firstname, etc are empty

    $cust->setFromArray($cols);
    // complains about unknown 'order_' fields.

}

有没有什么好方法可以从连接的行同时创建Order和Customer对象?或者我必须在没有表网关的情况下运行查询,获取原始结果集,并将每个字段逐个复制到新创建的对象中?

2 个答案:

答案 0 :(得分:1)

我使用此方法将数据库行字段分配给对象。我使用setter方法,但这也可能只用于对象的属性。

public function setOptions(array $options){
    $methods = get_class_methods($this);
    foreach ($options as $key => $value) {
        $method = 'set' . ucfirst($key);
        if (in_array($method, $methods)) {
            $this->$method($value);
        }
   }
   return $this;
}

答案 1 :(得分:1)

Zend_Db没有提供方便的方法来执行此操作。

假设,对于从多个表派生的行使用 Facade 模式是很好的。 facade类将跟踪哪些列属于每个相应的表。当您使用setFromArray()方法设置单个字段或整个字段时,Facade将知道如何将字段映射到每个表的Row对象,并将UPDATE语句应用于表(s受影响。

或者,您可以通过继承Zend_Db_Table_Row_Abstract来解决未知字段的问题,更改__set()行为以静默忽略未知列而不是抛出异常。

您不能拥有OO接口来执行SQL可以执行的所有操作。在沙子中必须有一些线路,您可以在其中确定已经涵盖的一组合理的常见案例,并且应该使用SQL来完成任何更复杂的事情。