是否有内置方法可以获取教义 2 实体中所有已更改/更新的字段

2022-08-30 07:54:42

假设我检索一个实体并使用 setter 修改其状态:$e

$e->setFoo('a');
$e->setBar('b');

是否有可能检索已更改字段的数组?

如果我的例子,我想检索结果foo => a, bar => b

PS:是的,我知道我可以修改所有访问器并手动实现此功能,但我正在寻找一些方便的方法来执行此操作


答案 1

您可以使用 来获取 .Doctrine\ORM\EntityManager#getUnitOfWorkDoctrine\ORM\UnitOfWork

然后只需通过 触发变更集计算(仅适用于托管实体)。Doctrine\ORM\UnitOfWork#computeChangeSets()

您也可以使用类似的方法,例如,如果您确切地知道要检查的内容,而无需迭代整个对象图。Doctrine\ORM\UnitOfWork#recomputeSingleEntityChangeSet(Doctrine\ORM\ClassMetadata $meta, $entity)

之后,您可以使用 来检索对对象所做的所有更改。Doctrine\ORM\UnitOfWork#getEntityChangeSet($entity)

把它放在一起:

$entity = $em->find('My\Entity', 1);
$entity->setTitle('Changed Title!');
$uow = $em->getUnitOfWork();
$uow->computeChangeSets(); // do not compute changes if inside a listener
$changeset = $uow->getEntityChangeSet($entity);

注意。如果尝试在update前的侦听器中获取更新的字段,请不要重新计算更改集,因为它已经完成。只需调用 getEntityChangeSet 即可获取对实体所做的所有更改。

警告:如注释中所述,此解决方案不应在 Doctrine 事件侦听器之外使用。这将破坏教义的行为。


答案 2

检查此公共(而不是内部)函数:

$this->em->getUnitOfWork()->getOriginalEntityData($entity);

来自 doctrine repo

/**
 * Gets the original data of an entity. The original data is the data that was
 * present at the time the entity was reconstituted from the database.
 *
 * @param object $entity
 *
 * @return array
 */
public function getOriginalEntityData($entity)

您所要做的就是在实体中实现 or 函数并进行差异化。像这样:toArrayserialize

$originalData = $em->getUnitOfWork()->getOriginalEntityData($entity);
$toArrayEntity = $entity->toArray();
$changes = array_diff_assoc($toArrayEntity, $originalData);

推荐