gpt4 book ai didi

php - Doctrine2 中的自定义集合

转载 作者:IT王子 更新时间:2023-10-29 00:04:09 25 4
gpt4 key购买 nike

刚开始使用 Doctrine2,想知道如何/是否可以使用自定义集合类。搜索指向我this part of the documentation :

Collection-valued persistent fields and properties must be defined in terms of the Doctrine\Common\Collections\Collection interface. The collection implementation type may be used by the application to initialize fields or properties before the entity is made persistent. Once the entity becomes managed (or detached), subsequent access must be through the interface type.

虽然我确信这对某些人来说是非常清楚的,但我对此有点模糊。

如果我设置我的实体来初始化(比如在 __construct() 中)集合变量到一个实现正确接口(interface)的类——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(不是 MANAGED、DETACHED 或 REMOVED),您就可以自由使用集合的具体实现类型,即使它并不漂亮。如果它不是新的,您必须只访问接口(interface)类型(最好是类型提示)。这意味着实现类型并不重要。当从数据库中检索到持久化的 MyEntity 实例时,它不会使用 MyCollection(构造函数不会被 Doctrine 调用,因为 Doctrine 只会重构已经存在的/持久化的对象,它永远不会创建"new"对象)。并且由于这样的实体是托管的,因此无论如何都必须通过接口(interface)类型进行访问。

现在说说计划。拥有自定义集合的更漂亮的方法是还具有自定义接口(interface)类型,例如 IMyCollection 和 MyCollection 作为实现类型。然后,为了使其与 Doctrine 2 持久性服务完美配合,您需要实现自定义 PersistentCollection 实现,例如 MyPersistentCollection,如下所示:

class MyPersistentCollection implements IMyCollection {
// ...
}

然后你会在映射中告诉 Doctrine 为那个集合使用 MyPersistentCollection 包装器(记住,一个 PersistentCollection wraps 一个集合实现类型,实现相同的接口(interface),所以它可以做所有的持久化在委托(delegate)给底层集合实现类型之前/之后工作。

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

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

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

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

关于php - Doctrine2 中的自定义集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3691943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com