Просто начал работать с Doctrine2, и мне интересно, как / если я могу использовать собственный класс коллекции. Запросы указывают мне на эту часть документации :
Перспективные постоянные поля и свойства коллекции должны быть определены в терминах интерфейса
Doctrine\Common\Collections\Collection
. Тип реализации коллекции может использоваться приложением для инициализации полей или свойств до того, как объект станет постоянным. Как только объект становится управляемым (или отсоединенным), последующий доступ должен быть через тип интерфейса.
Хотя я уверен, что это ясно для кого-то, я немного расплывчатый.
Если я настрою свой Entity для инициализации (скажем, в __construct()
), переменная коллекции для класса, который реализует правильный интерфейс, будет ли Doctrine2 продолжать использовать этот класс в качестве коллекции? Правильно ли я понимаю это?
Обновление . Кроме того, я собираюсь из разных потоков, что объект-заполнитель, используемый в ленивой загрузке, может влиять на то, как можно использовать пользовательскую коллекцию.
Позвольте мне попытаться выяснить, что возможно, невозможно и спланировано с примерами.
Цитата из руководства в основном означает, что у вас может быть следующий тип специальной реализации:
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
Другими словами, до тех пор, пока объект NEW (не УПРАВЛЯЕМЫЙ, ОТДЕЛЬНЫЙ или СНЯТЫЙ), вы можете использовать конкретный тип реализации коллекций, даже если его не очень. Если это не NEW, вы должны получить доступ только к типу интерфейса (и, в идеале, к нему наброски). Это означает, что тип реализации не имеет большого значения. Когда постоянный экземпляр MyEntity извлекается из базы данных, он не будет использовать MyCollection (конструкторы не будут вызываться Doctrine, поскольку Doctrine только восстанавливает уже существующие / постоянные объекты, он никогда не создает «новые»). И поскольку такой объект MANAGED, доступ должен происходить через тип интерфейса в любом случае.
Теперь к тому, что планируется. Более красивый способ создания пользовательских коллекций также иметь собственный тип интерфейса, например IMyCollection и MyCollection в качестве типа реализации. Затем, чтобы заставить его работать с службами Persistence 2 persistence, вам необходимо реализовать пользовательскую реализацию PersistentCollection, скажем, MyPersistentCollection, которая выглядит так:
class MyPersistentCollection implements IMyCollection { // ... }
Затем вы должны указать Doctrine в сопоставлении для использования оболочки MyPersistentCollection для этой коллекции (помните, PersistentCollection обертывает тип реализации коллекции, реализуя один и тот же интерфейс, чтобы он мог выполнять всю работу настойчивости до / после делегирования реализации базовой коллекции тип).
Таким образом, реализация пользовательской коллекции будет состоять из трех частей:
Это позволит не только создавать пользовательские коллекции, которые без труда работают с ORM Doctrine 2, но и писать только настраиваемый постоянный тип обертки, например, для оптимизации поведения ленивой загрузки / инициализации конкретной коллекции для конкретных приложений.
Пока это невозможно, но это будет. Это единственный действительно элегантный и полностью функциональный способ написания и использования полностью настраиваемых коллекций, которые безупречно интегрируются в прозрачную схему сохранения, предоставляемую Doctrine 2.
Нет, всякий раз, когда Doctrine возвращает вам реализацию интерфейса Doctrine \ Common \ Collections \ Collection, это будет экземпляр Doctrine \ ORM \ PersistentCollection. Вы не можете добавить больше пользовательской логики в коллекцию. Однако это даже не нужно.
Предположим, что у вас есть сущность (у Ордена есть много OrderItems), тогда метод вычисления общей суммы заказа не должен располагаться в коллекции, а в элементе заказа. Так как это место, где сумма имеет смысл в вашей модели домена:
class Order { private $items; public function getTotalSum() { $total = 0; foreach ($this->items AS $item) { $total += $item->getSum(); } return $total; } }
Однако коллекции – это только технические части ORM, они помогают внедрять и управлять ссылками между объектами, не более того.
Тот же вопрос здесь , со ссылкой на официальную страницу доктрины Jira с подробностями и статусом этой «функции» … Вы можете следить за развитием там!