[php] Doctrine 2 엔티티에서 변경 / 업데이트 된 모든 필드를 가져올 수있는 기본 제공 방법이 있습니까?


Answers

위에 설명 된 방법을 사용하여 엔티티의 변경 사항을 확인하려는 사용자에게는 큰주의 가 필요합니다.

$uow = $em->getUnitOfWork();
$uow->computeChangeSets();

$uow->computeChangeSets() 메서드는 위의 솔루션을 사용할 수 없게 만드는 방식으로 지속성 루틴에 의해 내부적으로 사용됩니다. 메소드에 주석으로 쓰여진 내용도 있습니다. @internal Don't call from the outside . $uow->computeChangeSets() 를 사용하여 엔티티에 대한 변경 사항을 확인한 후 메소드 끝에 (각 관리 대상마다) 다음 코드가 실행됩니다.

if ($changeSet) {
    $this->entityChangeSets[$oid]   = $changeSet;
    $this->originalEntityData[$oid] = $actualData;
    $this->entityUpdates[$oid]      = $entity;
}

$actualData 배열은 엔티티의 속성에 대한 현재 변경 사항을 보유합니다. 이것들이 $this->originalEntityData[$oid] 쓰여지 자마자, 아직 지속되지 않은 변경은 엔티티의 원래 속성으로 간주됩니다.

$em->persist($entity)$em->persist($entity) 의 변경 사항을 저장하기 위해 호출되면 나중에 $uow->computeChangeSets() 메소드도 포함되지만 이제는 엔티티에 대한 변경 사항을 찾을 수 없습니다. 엔티티는 아직 변경되지 않았기 때문에 변경 사항은 엔티티의 원래 속성으로 간주됩니다.

Question

엔티티 $e 검색하고 setter를 사용하여 상태를 수정한다고 가정 해 봅니다.

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

변경된 필드 배열을 검색 할 수 있습니까?

필자의 예에서는 foo => a, bar => b 를 검색하고 싶다.

추신 : 예, 모든 접근자를 수정하고 수동으로이 기능을 구현할 수 있음을 알고 있지만이 작업을 수행하는 편리한 방법을 찾고 있습니다.




누군가가 여전히 받아 들여진 대답과 다른 방식으로 관심이있는 경우 (그것은 저에게 효과가 없었고, 제 개인적인 견해로는이 방법보다 더 복잡했습니다).

JMS 시리얼 라이저 번들을 설치했고 각 엔티티와 각 특성에 @Group ({ "changed_entity_group"})을 추가 한 변경 사항을 고려했습니다. 이 방법을 사용하면 이전 엔티티와 업데이트 된 엔티티를 직렬화 할 수 있습니다. 그런 다음 $ oldJson == $ updatedJson이라고 말하면됩니다. 관심있는 속성이나 변경 사항을 고려하고 싶은 속성이 JSON과 같지 않을 경우 그리고 변경된 내용을 등록하려는 경우에도 배열로 바꾸고 차이점을 검색 할 수 있습니다.

나는 주로 엔티티들의 묶음의 몇몇 속성에 관심이 있었고 엔티티 전체에는 관심이 없었기 때문에이 방법을 사용했습니다. 이것이 유용한 예는 @PrePersist @PreUpdate가 있고 last_update 날짜가있는 경우입니다. 항상 업데이트되므로 개체가 작업 단위를 사용하여 업데이트되었고 그와 같은 것을 얻을 수 있습니다.

희망이 방법은 누구에게 도움이됩니다.




알림 정책을 사용 하여 변경 내용을 추적 할 수 있습니다.

우선, NotifyPropertyChanged 인터페이스를 구현합니다.

/**
 * @Entity
 * @ChangeTrackingPolicy("NOTIFY")
 */
class MyEntity implements NotifyPropertyChanged
{
    // ...

    private $_listeners = array();

    public function addPropertyChangedListener(PropertyChangedListener $listener)
    {
        $this->_listeners[] = $listener;
    }
}

그런 다음 데이터를 변경하는 모든 메소드에서 _onPropertyChanged 를 호출하여 엔티티를 아래와 같이 throw합니다.

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;
        }
    }
}



Links