Zend: два объекта, один ряд - PullRequest
5 голосов
/ 11 августа 2009

Я недавно начал использовать Zend Framework (1.8.4), чтобы предоставлять инструменты администратора для просмотра заказов на сайте корзины покупок.

Я хотел бы эффективно создать несколько объектов модели (Zend_Db_Table_Row_Abstract) из одной строки результатов базы данных.

Отношения просты: Заказ имеет одного Клиента (внешний ключ order_custid=customer.cust_id); у клиента много заказов.

Загрузка заказов достаточно проста. Используя метод, описанный здесь:

Моделирование объектов с несколькими связями таблиц в Zend Framework

... Тогда я мог бы схватить клиента за каждого.


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

Но когда вы загружаете длинный список заказов - скажем, 40 или более, с несколькими страницами - это мучительно медленно.

Затем я попытался присоединиться:


    $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 _ *.

Но как создать объект Customer из полей cust_ *, которые я нахожу в каждом из этих объектов Order?


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 ]

1 голос
/ 12 августа 2009

Zend_Db не предоставляет удобных методов для этого.

Гипотетически было бы разумно использовать шаблон Facade для строк, которые происходят из нескольких таблиц. Класс фасадов будет отслеживать, какие столбцы принадлежат каждой соответствующей таблице. Когда вы устанавливаете отдельное поле или целый набор полей с помощью метода setFromArray(), фасад будет знать, как сопоставить поля с объектами Row для каждой таблицы, и применять операторы UPDATE к соответствующим таблицам. 1008 *

Кроме того, вы можете обойти проблему неизвестных полей, создав подкласс Zend_Db_Table_Row_Abstract, изменив поведение __set() так, чтобы игнорировать неизвестные столбцы, а не выдавать исключение.

У вас не может быть интерфейса OO, чтобы делать все, что может делать SQL. В песке должна быть какая-то строка, где вы решаете, что рассмотрен разумный набор общих случаев, и что-либо более сложное должно быть сделано с SQL.

1 голос
/ 11 августа 2009

Я использую этот метод для назначения полей строки базы данных объектам. Я использую методы установки, но это, вероятно, также может быть сделано только со свойствами объекта.

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;
}
...