PDO使用外键获取类

时间:2017-09-19 19:54:17

标签: php mysql pdo

我有课程:

class Order {
    private $order_id;
    private $product;
    private $quantity;
}

class Product {
    private $product_id;
    private $name;
    private $price;
}

我也有那些MySql表:

orders:
+----------+------------------+----------+
| order_id |     product      | quantity |
+----------+------------------+----------+
| INTEGER  | INT(FOREIGN KEY) | INTEGER  |
+----------+------------------+----------+

products:
+------------+---------+---------+
| product_id |   name  |  price  |
+------------+---------+---------+
|   INTEGER  | VARCHAR | INTEGER |
+------------+---------+---------+

orders.product是与product.product_id关联的外键。

我想使用PDO从订单表中获取ID为123的订单,并自动将结果存储在Order类中。我知道有PDO::fetchObjectPDO::FETCH_CLASS,问题是他们不能递归地工作。

我知道我有一个简单的解决方案,即在一个查询中提取order_idquantity列,然后在第二个查询中提取产品字段。 有没有办法在一个查询中实现这个(使用JOIN)?

2 个答案:

答案 0 :(得分:0)

您可以在Order课程中进行魔术,例如:

$dbh = new PDO(...);

class Order {
    private $order_id;
    private $product_id;
    // IMPORTANT!
    // If class have `product` property - setter won't be called.
    // private $product;
    private $quantity;

    // PDO call this method only in case
    // class doesn't have property with same name like column in db.
    public function __set($name, $value) {
        // If property is product - call setProduct.
        if ($name === 'product') {
            $this->setProduct($value);
        }
    }

    public function setProduct($productId)
    {
        /** \PDO IMPORTANT global var here just for example, use better design. */
        global $dbh;
        $s = $dbh->prepare('SELECT * FROM products WHERE product_id = :pId');
        $s->bindParam(':pId', $productId, PDO::PARAM_INT);
        $s->execute();
        $this->product = $s->fetchAll(PDO::FETCH_CLASS, Product::class);
    }
}

$s = $dbh->prepare('SELECT * FROM orders WHERE order_id = :oId');
$s->bindValue(':oId', 123, PDO::PARAM_INT);
$s->execute();
$result = $s->fetchAll(PDO::FETCH_CLASS, Order::class);

答案 1 :(得分:0)

这是我之前的答案的扩展,作为另一种选择:

订单:

class Order {
    private $order_id;
    private $product_id;
    private $quantity;

    public function __set($name, $value) {
        if ($this->product === null) {
            $this->product = new Product();
        }
        switch ($name) {
            case 'productId':
                 $this->product->setProductId($value);
                break;
            case 'productName':
                 $this->product->setName($value);
                break;
            case 'productPrice':
                 $this->product->setPrice($value);
                break;
        }
    }
}

产品:

class Product {
    private $product_id;
    private $name;
    private $price;

    public function setProductId($product_id)
    {
        $this->product_id = $product_id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function setPrice($price)
    {
        $this->price = $price;
    }
}

Ussage:

$dbh = new PDO(...);
$s = $dbh->prepare('
    SELECT o.*, p.product_id productId, p.name productName, p.price productPrice
    FROM orders o
    JOIN products p ON o.product = p.product_id
    WHERE order_id = :oId
');
$s->bindValue(':oId', 123, PDO::PARAM_INT);
$s->execute();
$result = $s->fetchAll(PDO::FETCH_CLASS, Order::class);