我有课程:
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::fetchObject
和PDO::FETCH_CLASS
,问题是他们不能递归地工作。
我知道我有一个简单的解决方案,即在一个查询中提取order_id
和quantity
列,然后在第二个查询中提取产品字段。
有没有办法在一个查询中实现这个(使用JOIN)?
答案 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);