如何在Doctrine2中访问PrePersist LifecycleCallback上的旧值

sch*_*ldi 12 php events lifecycle doctrine

我在Doctrine2中有一个实体,并将HasLivecycleCallbacks与PrePersist一起使用.一般来说,这工作正常,但我想更改版本,当我的实体中的某些字段更改.我有机会获得旧的价值观吗?或者只是已更改的键?

/**
 * @ORM\HasLifecycleCallbacks
 */
class Person {


    /**
     * @PrePersist
     * @PreUpdate
     */
    public function increaseVersion() {


            if ( $this->version == null ) {
                $this->version = 0;
            }
            // only do this, when a certain attribute changed
            $this->version++;
    }
}
Run Code Online (Sandbox Code Playgroud)

Gor*_*don 25

这取决于我们正在谈论的LifecycleEvent.PrePersist和PreUpdate是不同的事件.

在实体更新之前,会触发PreUpdate.这将为您提供一个PreUpdateEventArgs对象,它是一个扩展LifecycleEventArgs对象.这将允许您查询已更改的字段并允许您访问旧值和新值:

if ($event->hasChangedField('foo')) {
    $oldValue = $event->getOldValue('foo');
    $newValue = $event->getNewValue('foo');
}
Run Code Online (Sandbox Code Playgroud)

您还可以获取所有更改的字段值 getEntityChangeSet(),这将为您提供如下数组:

array(
    'foo' => array(
        0 => 'oldValue',
        1 => 'newValue'
    ),
    // more changed fields (if any) …
)
Run Code Online (Sandbox Code Playgroud)

另一方面,PrePersist假定一个新的实体(想想插入新行).在PrePersist中,您将获得一个LifecycleEventArgs只能访问实体和对象的对象EntityManager.从理论上讲,您可以通过它访问UnitOfWork(跟踪实体的所有更改)EntityManager,因此您可以尝试

$changeSet = $event->getEntityManager()->getUnitOfWork()->getEntityChangeSet(
    $event->getEntity()
);
Run Code Online (Sandbox Code Playgroud)

获取要保留的实体的更改.然后,您可以检查此数组是否有更改的字段.但是,由于我们讨论的是插入而不是更新,我假设所有字段都被视为"已更改",旧值可能全部为空.我不确定,这会在您需要的时候起作用.

进一步参考:http://docs.doctrine-project.org/en/2.0.x/reference/events.html

  • @Martin OP 询问如何使用 PrePersist,所以我向他解释了如何使用 PrePersist 做到这一点,同时解释了为什么这不是他想要的,而他应该使用什么来代替。重点是提供一个全面的答案。 (2认同)