类构造函数中的PHP PDO查询

类构造函数中的PHP PDO查询,php,class,oop,pdo,instantiation,Php,Class,Oop,Pdo,Instantiation,我仍然在学习OOP,但我正在尝试使用singleton数据库连接对象1获得的数据创建一个“Order”对象 我通过获取一个订单号数组,然后对它们进行迭代2,创建订单对象,将订单号传递给类,从中我希望订单类使用singleton数据库连接查询数据库,以获取关于每个订单的更多信息并填充其属性3。我的想法是,如果Order类在Order标识符之外是“自包含的”,那么它将更易于维护,并且非常灵活 我知道我可以从getOrders获取数据并将其传递到类中,但如果我决定需要另一个字段,我不想修改50个不同的

我仍然在学习OOP,但我正在尝试使用singleton数据库连接对象1获得的数据创建一个“Order”对象

我通过获取一个订单号数组,然后对它们进行迭代2,创建订单对象,将订单号传递给类,从中我希望订单类使用singleton数据库连接查询数据库,以获取关于每个订单的更多信息并填充其属性3。我的想法是,如果Order类在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个order对象,但是只有最后一个包含任何数据。您还可以看到,我想对每个订单的Customer对象执行类似的操作

我还尝试创建一个新的数据库连接实例,这确实会为创建的每个对象获取数据,但是我知道我可能会创建很多数据库连接

这是正确的方法吗?还是我完全错了方向

我会先简单点:

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);

这可以通过引入位于网关和数据类之间的数据映射器类来进一步改进。您可以在搜索数据映射器模式时了解这一点。

类构造函数不应该做任何实际工作,只需进行设置。他们通常只需要将传入的参数分配给成员变量。如果可以避免的话,您绝对不应该在构造函数中执行查询。您的子类应该有一个getOrder方法,该方法执行实际查询,并在调用构造函数后由消费代码调用。谢谢@GordonM,这是另一个经验教训!把它放在那里感觉很不对劲,但我正在尽我最大的努力获得一个一键解决方案来填充这个类。我把所有东西都移动到了$this->order\u number=$order\u number;创建一个Order->getOrder方法,并在访问每个对象时调用它。只需记住需要调用getOrder来填充它!