Doctrine2中的自定义集合

Tim*_*tle 14 php collections orm doctrine-orm

刚刚开始使用Doctrine2,我想知道如何/如果我可以使用自定义集合类.搜索指向我的文档的这一部分:

必须根据Doctrine\Common\Collections\Collection接口定义集合值持久字段和属性.应用程序可以使用集合实现类型在实体持久化之前初始化字段或属性.一旦实体被管理(或分离),后续访问必须通过接口类型.

虽然我确信这对某人来说很清楚,但我对它有点模糊.

如果我设置我的实体来初始化(比如说__construct())集合变量到实现正确接口的类 - Doctrine2会继续使用该类作为集合吗?我理解正确吗?

更新:此外,我从各种线程收集延迟加载中使用的占位符对象可能会影响自定义集合的使用方式.

rom*_*anb 20

让我试着用实例来澄清可能的,不可能的和有计划的.

手册中的引用基本上意味着您可以使用以下自定义实现类型:

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() { ... }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以按如下方式使用它:

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
Run Code Online (Sandbox Code Playgroud)

换句话说,只要实体是NEW(不是MANAGED,DETACHED或REMOVED),您就可以自由地使用具体的实现类型的集合,即使它不漂亮.如果它不是NEW,则必须只访问接口类型(理想情况下是类型提示).这意味着实现类型并不重要.当一个持久myEntity所实例从数据库中检索,也不会使用MyCollection的(构造函数没有被调用的学说,以往,因为只有学说已经重新构成现有/持久性对象,它从不创建"新"的).由于这样的实体是MANAGED,因此无论如何都必须通过接口类型进行访问.

现在到了计划的目的.拥有自定义集合的更美妙的方法是也有一个自定义接口类型,比如IMyCollection和MyCollection作为实现类型.然后,使之与教条2持久性服务完美地工作,你将需要实现自定义PersistentCollection实现,比方说,MyPersistentCollection它看起来像这样:

class MyPersistentCollection implements IMyCollection {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

然后,你会告诉学说在映射使用MyPersistentCollection包装该集合(记住,一个PersistentCollection 包装集合实现类型,实现相同的接口,这样,可以在之前做的所有持久性的工作/委托给底层集合实施后类型).

因此,自定义集合实现将包含3个部分:

  1. 接口类型
  2. 实现类型(实现接口类型)
  3. 持久包装器类型(实现接口类型)

这不仅可以编写与Doctrine 2 ORM无缝协作的自定义集合,而且还可以只编写自定义持久包装器类型,例如优化特定集合的延迟加载/初始化行为以满足特定的应用程序需求.

现在还不可能做到这一点,但它会.这是编写和使用完全自定义集合的唯一真正优雅且功能齐全的方式,这些集合完美地集成在Doctrine 2提供的透明持久性方案中.