Zend:两个对象,一行

发布于 2024-07-30 13:57:41 字数 1731 浏览 7 评论 0原文

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

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

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

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

在 Zend 中对具有多个表关系的对象进行建模框架

...然后我就可以为每个框架抓住客户。


    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 对象? 或者我必须在没有表网关的情况下运行查询,获取原始结果集,并将每个字段一一复制到新创建的对象中?

I've recently started using Zend Framework (1.8.4), to provide admin tools for viewing the orders of a shopping cart site.

What I'd like to do is to efficiently create multiple model (Zend_Db_Table_Row_Abstract) objects from a single database result row.

The relationship is simple:
an Order has one Customer (foreign key order_custid=customer.cust_id);
a Customer has many Orders.

Loading the orders is easy enough. Using the method documented here:

Modeling objects with multiple table relationships in Zend Framework

...I could then grab the customer for each.


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

But when you're loading a long list of orders - say, 40 or more, a pageful - this is painfully slow.

Next I tried a 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);

This gives me an array of order objects. print_r($orders) shows that each of them contains the column list I expect, in a protected member, with raw field names order_* and cust_*.

But how to create a Customer object from the cust_* fields that I find in each of those Order objects?


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.

}

Is there any good way to create an Order and a Customer object simultaneously from the joined rows? Or must I run the query without the table gateway, get a raw result set, and copy each of the fields one-by-one into newly created objects?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑饮青盏花 2024-08-06 13:57:44

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

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

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

你不可能用一个面向对象的接口来完成 SQL 能做的所有事情。 必须有一条界限,您可以确定已经涵盖了一组合理的常见情况,并且任何更复杂的事情都应该使用 SQL 来完成。

Zend_Db doesn't provide convenience methods to do this.

Hypothetically, it'd be nifty to use a Facade pattern for rows that derive from multiple tables. The facade class would keep track of which columns belong to each respective table. When you set an individual field or a whole bunch of fields with the setFromArray() method, the facade would know how to map fields to the Row objects for each table, and apply UPDATE statements to the table(s) affected.

Alternatively, you could work around the problem of unknown fields by subclassing Zend_Db_Table_Row_Abstract, changing the __set() behavior to silently ignore unknown columns instead of throwing an exception.

You can't have an OO interface to do everything SQL can do. There must be some line in the sand where you decide a reasonable set of common cases have been covered, and anything more complex should be done with SQL.

〃温暖了心ぐ 2024-08-06 13:57:44

我使用此方法将数据库行字段分配给对象。 我使用 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;
}

I use this method to assign database row fields to objects. I use setter methods, but this could probably be also done with only properties on object.

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文