1. ホーム
  2. php

[解決済み] Doctrine 2 のエンティティで変更/更新されたフィールドをすべて取得するビルトインの方法はありますか?

2023-03-19 15:14:16

質問

あるエンティティを取得するとします。 $e を取得し、セッターでその状態を変更するとします。

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

変更されたフィールドの配列を取得することは可能でしょうか?

私の例の場合、私は以下のものを取得したいと思います。 foo => a, bar => b を結果的に

PS: そうです、すべてのアクセサを変更してこの機能を手動で実装できることは知っていますが、これを行うための何か便利な方法を探しています。

どのように解決するのですか?

この場合 Doctrine\ORM\EntityManager#getUnitOfWork を使うことで Doctrine\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);

注意 更新されたフィールドを取得しようとすると を preUpdate リスナーの内部で の中で、更新されたフィールドを取得しようとしている場合、すでに行われているので、変更セットを再計算しないでください。単にエンティティに行われたすべての変更を取得するために getEntityChangeSet を呼び出すだけです。

警告です。 コメントで説明されているように、この解決方法は Doctrine のイベントリスナーの外側で使ってはいけません。これは Doctrine の動作を壊してしまいます。