2009-08-11 4 views
5

최근 Zend Framework (1.8.4)를 사용하여 장바구니 사이트의 주문을 볼 수있는 관리 도구를 제공하기 시작했습니다.Zend : 두 개의 객체, 하나의 행

하나의 데이터베이스 결과 행에서 여러 모델 (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 이상 말을하는 pageful -이 고통스럽게 느립니다.

는 다음 나는 시도한 가입 :


    $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 개체를 동시에 만드는 좋은 방법이 있습니까? 또는 테이블 게이트웨이없이 쿼리를 실행하고 원시 결과 집합을 가져 와서 각 필드를 새로 만든 개체에 하나씩 복사해야합니까?

+0

내가 아는 한 Zend_Db는 그렇게하지 않습니다. 나는 해결책에도 매우 관심이있다. – markus

답변

1

Zend_Db은이를 수행하는 데 편리한 방법을 제공하지 않습니다.

여러 테이블에서 파생 된 행에 대해 Facade 패턴을 사용하는 것이 좋습니다. Facade 클래스는 각각의 테이블에 속한 컬럼을 추적합니다. setFromArray() 메서드를 사용하여 개별 필드 나 전체 필드를 설정하면 facade는 각 테이블의 Row 개체에 필드를 매핑하는 방법을 알게되고 영향을받는 테이블에 UPDATE 문을 적용합니다.

Zend_Db_Table_Row_Abstract의 서브 클래스를 지정하고 __set() 비헤이비어를 변경하여 알 수없는 열을 자동으로 무시하도록 변경하여 알 수없는 필드 문제를 해결할 수 있습니다.

SQL이 할 수있는 모든 일을하기 위해 OO 인터페이스를 사용할 수 없습니다. 합리적인 세트의 일반적인 사례가 포함되어 있다고 판단되는 모래에 줄이 있어야하며 SQL을 사용하여 더 복잡한 작업을 수행해야합니다.

+0

Hibernate (Java)는 우아하게 처리한다. 할 경우 : query.addEntity (Order.class) query.addEntity (Customer.class); ... 그러면 반환되는 것은 List입니다. 각 행은 지정된 순서로 두 객체 유형을 가진 배열입니다. –

+0

멋진데. 그러나 Hibernate는 가치가있는 것을 위해 499 만 라인을 넘는 Java 코드로 구성됩니다. Zend_Db는 약 2,700 줄의 PHP 코드입니다. PHP 플랫폼의 런타임 특성으로 인해 코드 팽창에 더 민감하므로 가장 일반적으로 사용되는 기능 만 구현하여 라이브러리를 간결하게 만드는 것이 더 중요합니다. –

+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; 
} 
관련 문제