2009-08-11 27 views
5

Gần đây tôi đã bắt đầu sử dụng Zend Framework (1.8.4), để cung cấp công cụ quản trị để xem các đơn đặt hàng của trang web giỏ hàng.Zend: Hai đối tượng, một hàng

Điều tôi muốn làm là tạo các mô hình nhiều mô hình (Zend_Db_Table_Row_Abstract) hiệu quả từ một hàng kết quả cơ sở dữ liệu duy nhất.

Mối quan hệ đơn giản: một Đơn đặt hàng có một Khách hàng (khóa ngoài order_custid=customer.cust_id); Khách hàng có nhiều Đơn đặt hàng.

Tải đơn đặt hàng dễ dàng. Sử dụng phương pháp ghi nhận ở đây:

Modeling objects with multiple table relationships in Zend Framework

... Sau đó tôi có thể lấy các khách hàng đối với từng.


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

Nhưng khi bạn tải một danh sách dài các đơn đặt hàng - ví dụ: 40 trở lên, một trang - điều này rất chậm.

Tiếp theo, tôi cố gắng lệnh 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); 

này mang lại cho tôi một mảng của các đối tượng theo thứ tự. print_r($orders) cho thấy mỗi một trong số chúng chứa danh sách cột mà tôi mong đợi, trong một thành viên được bảo vệ, với tên trường thô order_ * và cust_ *.

Nhưng cách tạo đối tượng khách hàng từ các trường cust_ * mà tôi tìm thấy trong từng đối tượng 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. 

} 

Có cách nào tốt để tạo đối tượng đặt hàng và khách hàng đồng thời từ các hàng được nối không? Hoặc tôi phải chạy truy vấn mà không có cổng bảng, có được một tập hợp kết quả thô và sao chép từng trường một lần vào các đối tượng mới được tạo không?

+0

Theo như tôi biết Zend_Db không làm điều đó. Tôi cũng rất thích một giải pháp. – markus

Trả lời

1

Zend_Db không cung cấp các phương pháp tiện lợi để thực hiện việc này.

Giả thuyết, sẽ rất tiện lợi khi sử dụng mẫu Mặt tiền cho các hàng có nguồn gốc từ nhiều bảng. Lớp mặt tiền sẽ theo dõi các cột thuộc về mỗi bảng tương ứng. Khi bạn đặt một trường riêng lẻ hoặc toàn bộ một loạt trường bằng phương thức setFromArray(), mặt tiền sẽ biết cách ánh xạ trường vào đối tượng Hàng cho từng bảng và áp dụng các câu lệnh UPDATE cho (các) bảng bị ảnh hưởng. Ngoài ra, bạn có thể giải quyết vấn đề của các trường không xác định bằng cách phân lớp Zend_Db_Table_Row_Abstract, thay đổi hành vi __set() để bỏ qua các cột không xác định một cách âm thầm thay vì ném một ngoại lệ.

Bạn không thể có giao diện OO để thực hiện mọi thứ mà SQL có thể thực hiện. Phải có một số dòng trong cát, nơi bạn quyết định một tập hợp các trường hợp phổ biến hợp lý đã được đề cập đến và mọi thứ phức tạp hơn sẽ được thực hiện với SQL.

+0

Hibernate (Java) làm nó thanh lịch; nếu bạn làm: query.addEntity (Order.class) query.addEntity (Customer.class); ... sau đó những gì bạn nhận được trở lại là một Danh sách, mỗi hàng trong số đó là một mảng với hai loại đối tượng đó theo thứ tự được chỉ định. –

+0

Thật tuyệt. Nhưng đối với những gì nó có giá trị, Hibernate bao gồm> 490.000 dòng mã Java. Zend_Db là khoảng 2.700 dòng mã PHP. Do tính chất thời gian chạy của nền tảng PHP, nó nhạy cảm hơn với mã bloat, và do đó điều quan trọng hơn là làm cho các thư viện gọn gàng, chỉ thực hiện trên các tính năng được sử dụng phổ biến nhất. –

+0

Điểm tốt! Có, tôi có thể thấy sự cần thiết phải giữ một kích thước khuôn khổ trong lý do. –

1

Tôi sử dụng phương pháp này để chỉ định trường hàng cơ sở dữ liệu cho các đối tượng. Tôi sử dụng phương pháp setter, nhưng điều này có lẽ cũng có thể được thực hiện chỉ với các thuộc tính trên đối tượng.

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; 
} 
Các vấn đề liên quan