Позвольте мне попытаться уточнить, что возможно, что невозможно и что планируется с примерами.
Цитата из руководства в основном означает, что вы можете иметь следующий пользовательский тип реализации:
use Doctrine\Common\Collections\Collection;
// MyCollection is the "implementation type"
class MyCollection implements Collection {
// ... interface implementation
// This is not on the Collection interface
public function myCustomMethod() { ... }
}
Теперь вы можете использовать его следующим образом:
class MyEntity {
private $items;
public function __construct() {
$this->items = new MyCollection;
}
// ... accessors/mutators ...
}
$e = new MyEntity;
$e->getItems()->add(new Item);
$e->getItems()->add(new Item);
$e->getItems()->myCustomMethod(); // calling method on implementation type
// $em instanceof EntityManager
$em->persist($e);
// from now on $e->getItems() may only be used through the interface type
Другими словами, до тех пор, пока сущность является НОВОЙ (не УПРАВЛЯЕМОЙ, НЕ ОБНАРУЖЕННОЙ или УДАЛЕННОЙ), вы можете использовать конкретный тип реализации коллекций, даже еслиэто не красиво.Если он не НОВЫЙ, вы должны получить доступ только к типу интерфейса (и в идеале к нему подсказка типа).Это означает, что тип реализации не имеет большого значения.Когда постоянный экземпляр MyEntity извлекается из базы данных, он не будет использовать MyCollection (конструкторы никогда не вызываются Doctrine, поскольку Doctrine только воссоздает уже существующие / постоянные объекты, но никогда не создает «новые»).И поскольку такая сущность УПРАВЛЯЕТСЯ, доступ в любом случае должен осуществляться через тип интерфейса.
Теперь к тому, что планируется.Более красивый способ иметь пользовательские коллекции - это также иметь пользовательский тип интерфейса, например, IMyCollection и MyCollection в качестве типа реализации.Затем, чтобы он идеально работал со службами персистентности Doctrine 2, вам необходимо реализовать собственную реализацию PersistentCollection, скажем, MyPersistentCollection, которая выглядит следующим образом:
class MyPersistentCollection implements IMyCollection {
// ...
}
Затем вы указываете Doctrine в отображении использоватьоболочка MyPersistentCollection для этой коллекции (не забывайте, что PersistentCollection включает тип реализации коллекции, реализующий тот же интерфейс, так что он может выполнять всю работу по сохранению до / после делегирования базовому типу реализации коллекции).
Таким образом, реализация пользовательской коллекции будет состоять из 3 частей:
- Тип интерфейса
- Тип реализации (реализует тип интерфейса)
- Постоянный тип оболочки (реализует тип интерфейса)
Это позволит не только создавать пользовательские коллекции, которые, как кажется, работают с ORM в Doctrine 2, но и писать только пользовательский тип персистентной оболочки, например, для оптимизации.Настройте ленивую загрузку / инициализацию определенного набора для конкретных нужд приложения.
Пока это невозможно сделать, но это будет так.Это единственный действительно элегантный и полностью функциональный способ написания и использования полностью пользовательских коллекций, которые безупречно интегрируются в прозрачную схему персистентности, представленную в Doctrine 2.