엔티티를 취득했다고 칩시다.$e
설정기를 사용하여 상태를 수정합니다.
$e->setFoo('a'); $e->setBar('b');
변경된 필드 배열을 가져올 수 있습니까?
이 예제의 경우 검색하려고 합니다.foo => a, bar => b
결과적으로.
PS: 네, 모든 액세스 장치를 변경하여 이 기능을 수동으로 구현할 수 있지만, 이 기능을 쉽게 구현할 수 있는 방법을 찾고 있습니다.
질문에 대한 답변
사용할 수 있습니다.DoctrineORMEntityManager#getUnitOfWork
을 얻다DoctrineORMUnitOfWork
.
다음으로 변경 세트 계산(관리 엔티티에서만 동작)을 트리거합니다.DoctrineORMUnitOfWork#computeChangeSets()
.
다음과 같은 유사한 방법을 사용할 수도 있습니다.DoctrineORMUnitOfWork#recomputeSingleEntityChangeSet(DoctrineORMClassMetadata $meta, $entity)
전체 객체 그래프에서 반복하지 않고 무엇을 확인하고 싶은지 정확히 알고 있는 경우.
그 후 를 사용할 수 있습니다.DoctrineORMUnitOfWork#getEntityChangeSet($entity)
오브젝트에 대한 모든 변경 내용을 가져옵니다.
종합:
$entity = $em->find('MyEntity', 1); $entity->setTitle('Changed Title!'); $uow = $em->getUnitOfWork(); $uow->computeChangeSets(); // do not compute changes if inside a listener $changeset = $uow->getEntityChangeSet($entity);
참고. 업데이트 전 수신기 내에서 업데이트된 필드를 가져오려고 할 경우 이미 수행된 변경 집합은 다시 계산하지 마십시오.단순히 getEntityChangeSet을 호출하여 엔티티에 대한 모든 변경을 가져옵니다.
경고:코멘트에서 설명한 바와 같이 이 솔루션은 독트린이벤트 리스너 이외에서는 사용할 수 없습니다.이것으로 독트린의 행동이 깨질 것이다.
다음 퍼블릭(내부 아님) 기능을 확인합니다.
$this->em->getUnitOfWork()->getOriginalEntityData($entity);
교리보고에서:
/**
* 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)
이 기능을 구현하기만 하면 됩니다.toArray
또는serialize
기능하여 차이를 만듭니다.이런 느낌:
$originalData = $em->getUnitOfWork()->getOriginalEntityData($entity); $toArrayEntity = $entity->toArray(); $changes = array_diff_assoc($toArrayEntity, $originalData);
위에서 설명한 방법을 사용하여 기업의 변경 사항을 확인하고자 하는 경우 크게 주의하시기 바랍니다.
$uow = $em->getUnitOfWork(); $uow->computeChangeSets();
그$uow->computeChangeSets()
method는 상기의 솔루션을 사용할 수 없게 하는 방법으로 영속적인 루틴에 의해 내부적으로 사용됩니다.이 방법에 대한 코멘트에는 다음과 같은 내용이 기재되어 있습니다.@internal Don't call from the outside
. 다음 엔티티에 대한 변경 내용을 확인한 후$uow->computeChangeSets()
다음 코드 조각은 메서드의 마지막에 실행됩니다(관리 대상 엔티티별로).
if ($changeSet) {
$this->entityChangeSets[$oid]
= $changeSet;
$this->originalEntityData[$oid] = $actualData;
$this->entityUpdates[$oid]
= $entity; }
그$actualData
array는 엔티티의 속성에 대한 현재 변경 사항을 유지합니다.이것들은 에 써지는 대로$this->originalEntityData[$oid]
이 변경은 아직 지속되지 않은 엔티티의 원래 속성으로 간주됩니다.
그 후,$em->persist($entity)
엔티티에 대한 변경을 저장하기 위해 호출됩니다.또한 메서드도 포함됩니다.$uow->computeChangeSets()
그러나 아직 지속되지 않은 변경은 엔티티의 원래 속성으로 간주되기 때문에 엔티티에 대한 변경은 찾을 수 없습니다.
먼저 Notify를 구현합니다.PropertyChanged 인터페이스:
/**
* @Entity
* @ChangeTrackingPolicy("NOTIFY")
*/ class MyEntity implements NotifyPropertyChanged {
// ...
private $_listeners = array();
public function addPropertyChangedListener(PropertyChangedListener $listener)
{
$this->_listeners[] = $listener;
} }
다음으로 데이터를 변경하는 모든 메서드에 대해 다음과 같이 _onPropertyChanged를 호출합니다.
class MyEntity implements NotifyPropertyChanged {
// ...
protected function _onPropertyChanged($propName, $oldValue, $newValue)
{
if ($this->_listeners) {
foreach ($this->_listeners as $listener) {
$listener->propertyChanged($this, $propName, $oldValue, $newValue);
}
}
}
public function setData($data)
{
if ($data != $this->data) {
$this->_onPropertyChanged('data', $this->data, $data);
$this->data = $data;
}
} }
변경 내용이 반환됩니다.
$entityManager->getUnitOfWork()->getEntityChangeSet($entity)