2013-07-24 76 views
1

我仍然在處理OOP,但我試圖使用單身數據庫連接對象(#1)獲取的數據創建'Order'對象。在類構造函數中的PHP PDO查詢

我通過獲取一組訂單號然後迭代它們(#2),創建Order對象,將訂單號傳遞給類,從我希望Order類使用查詢數據庫的位置單身數據庫連接來獲取關於每個訂單的更多信息並填充它的屬性(#3)。我的想法是,Order類如果在訂單標識符之外是「自包含的」,將更容易維護並且非常靈活。

我知道我只能從getOrders()獲取數據並將其傳遞到類中,但如果我決定需要另一個字段,我不想修改50個不同的查詢!

這工作到一個點,但如果我有10個訂單,只有最後一個訂單對象填充數據庫中的數據。我假設數據庫連接在有時間完成並填充它的屬性之前被重用?

下面是一些代碼...

class Example { 
    protected $dBCon; 

    #1 
    //class constructor 
    public function __construct() { 
    //connect to SQL database 
     $this->dBCon = DB::getInstance(); 
    } 

    #2 
    public function getOrders() { 
     $orders = array(); 
     $sql="SELECT ORDNUMBER FROM ORDERS"; 
     $result = $this->dBCon->executeCommand($sql); 
     foreach ($result as $row) { 
      $order = new Order($row['ORDNUMBER']); 
      $orders[] = $order; 
     } 
     return $orders; 
     } 

} 

class Order extends Example { 
    public $order_number; 
    public $customer; 
    public $price_list; 

    #3 
    public function __construct($order_number) {   
    if ($order_number) { 
     //create Order from existing order 
     //connect to SQL database 
     $this->dBCon = DB::getInstance(); 
     $sql = "SELECT * FROM ORDERS WHERE ORDNUMBER = ?"; 
     $result = $this->dBCon->executePreparedStatement($sql, array($order_number)); 
     $this->order_number = $order_number; 
     foreach ($result as $row) {    
      $this->customer = new Customer($row['CUSTOMER']); 
      $this->price_list = $row['PRICELIST']; 
     } 
    } 
} 

所以調用getOrders()給我,例如,10點階的對象,但是隻有最後一個包含任何數據。您也可以看到我想爲每個訂單執行與Customer對象類似的操作。

我也試過創建一個新的數據庫連接實例,這確實爲每個創建的對象獲取數據,但是我意識到我可能會創建大量的數據庫連接!

這是正確的方式去做這件事,或者我完全得到了OOP棒的錯誤結局!

+1

類的構造函數不應該做任何真正的工作,只是設置。它們通常不應該做比將參數傳遞給成員變量更多的事情。如果你完全可以避免它,你絕對不應該在構造函數中進行查詢。你的子類應該有一個getOrder方法來完成實際的查詢,並且在構造函數被調用之後被消費代碼調用。 – GordonM

+0

謝謝@GordonM,另一個教訓!它覺得很不對勁,但我正在盡力爭取一個解決方案來填充課程。我把所有東西都移到了$ this-> order_number = $ order_number;到Order-> getOrder()方法,並在每個對象被訪問時調用它。它只是記住getOrder()需要被調用才能填充它! – Harry

回答

0

我會使Order很簡單第一:

class Order 
{ 
    public $order_number; 
    public $customer; 
    public $price_list; 
} 

它知道任何有關SQL或任何形式的數據庫。然後,您可以選擇通過一個或兩個步驟加載這些對象;現在就讓我們一步完成。

class OrderGateway 
{ 
    public static function getOrders(PDO $db) 
    { 
     $orders = array(); 

     $stmt = $db->query('SELECT * FROM `orders`'); 
     foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) { 
      $order = new Order(); 
      $order->order_number = $row['ORDNUMBER']; 
      $order->customer = new Customer($row['CUSTOMER']); 
      $order->price_list = $row['PRICELIST']; 

      $orders[] = $order; 
     } 

     return $orders; 
    } 
} 

$orders = OrderFactory::getOrders($db); 

這可以通過引入位於網關和數據類之間的數據映射器類來進一步改進。當您搜索「數據映射器模式」時,您可以閱讀這些內容。