php doctrine保存不同实体的集合

I have interface:

interface Product
{
    function getAmount();
}

and php doctine entities:

/**
 * @ORM\Table(name="orders")
 * @ORM\Entity
 */
class Order
{
    private $products = array();

    public function addProduct(Product $product){
        $this->products[] = $product;
    }

    public function getProducts() {
        return $this->products;
    }

    function getAmount() {
        $amount = 0;
        foreach ($this->products as $product) {
            $amount += $product->getAmount();
        }

        return $amount;
    }
}
/**
 * @ORM\Table(name="books")
 * @ORM\Entity
 */
class Book implements Product
{
    function getAmount() {
        return 1;
    }
}
/**
 * @ORM\Table(name="pens")
 * @ORM\Entity
 */
class Pen implements Product
{
    function getAmount()
    {
        return 2;
    }
}

Book, Pen - are different entities and table. How to implement relationship Order::products with collection of Books, Pens, etc(for save in database)?

I understand that two solutions to this problem. The first is when saving(and loading) to the database manually convert this relationship to map(array of entities names and ids). This decision I do not like. And the second is to correct architecture. I do not know how. Most likely already have a ready-made solution ... Help please.

i'am not sure you can get it exactly that way.

  • whether you define a separate Entity Poduct and add a column product_type where you tell whether it book, pen or what ever.

    in entity Product that property should be defined as enum and it can be tricky(depends on what do you use besides doctrine)

  • or you make it for each product type (what can be pretty fast to a nightmare). I'd guess you have ManyToMany Relation. most probably it should look smth. like that.

in Order

 /**
 * @ManyToMany(targetEntity="Book")
 * @JoinTable(name="Order_Book",
 *      joinColumns={@JoinColumn(name="book_id", referencedColumnName="id")},
 *      inverseJoinColumns={@JoinColumn(name="order_id", referencedColumnName="id")}
 *      )
 */
 protected $book;

 /**
 * @ManyToMany(targetEntity="Pen")
 * @JoinTable(name="Order_Pen",
 *      joinColumns={@JoinColumn(name="pen_id", referencedColumnName="id")},
 *      inverseJoinColumns={@JoinColumn(name="order_id", referencedColumnName="id")}
 *      )
 */
 protected $pen;

and in Book:

  /*
  * @ManyToMany(targetEntity="Order", mappedBy="book")
  */
  protected $order;

with Pen and others the same way.