在存储数据之前执行的 Symfony 2 postUpdate

Symfony 2 postUpdate executed before data is stored

我现在在下面卡住了大约一天

我在我的帐户实体上创建了一个侦听器,它侦听 prePersistpreUpdatepostPersistpostUpdate。我以为postUpdate是在数据入库后执行的,现在我怀疑了

倾听者

/**
 * Account listener
 */
class AccountListener
{

    private $container;

    /**
     * Constructor
     *
     * @param ContainerInterface $container
     */
    public function __construct(ContainerInterface $container)
    {
        $this->container = $container;
    }

    /**
     * Pre persist
     *
     * @param LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Accounts) {
            $this->checkIfApiCallIsNeeded($entity, $args);
        }
    }

    /**
     * pre update
     *
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Accounts) {
            $this->checkIfApiCallIsNeeded($entity, $args);
        }
    }

    /**
     * Post persist
     *
     * @param LifecycleEventArgs $args
     */
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Accounts) {
            $this->callApi($entity, $args);
        }
    }

    /**
     * Post update
     *
     * @param LifecycleEventArgs $args
     */
    public function postUpdate(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if ($entity instanceof Accounts) {
            $this->callApi($entity, $args);
        }
    }

    /**
     * Checks if a update should be send to the api and store the result in db
     * 
     * @param  Accounts           $account
     * @param  LifecycleEventArgs $args 
     */
    private function checkIfApiCallIsNeeded(Accounts $account, LifecycleEventArgs $args)
    {

        $importantProperties = array(
            'contactName',
            'address',
            'zipPostal',
            'city',
            'stateProvince',
            'country'
        );

        $callApi = 0;

        $uow = $args->getEntityManager()->getUnitOfWork();
        $changeset = $uow->getEntityChangeSet($account);

    /**
     * Check if one of the important properties has been changed 
     */
        foreach ($importantProperties as $property) {
            if (array_key_exists($property, $changeset)) {
                $callApi = 1;
            }
        }

        /**
         * Store in database
         */
        $account->setNeedUpdate($callApi);
    }

    /**
     * Update account to api
     *
     * @param Accounts $account
     */
    private function callApi(Accounts $account, LifecycleEventArgs $args)
    {
        $callApi = $account->getNeedUpdate();
        $accountId = $account->getId();

        if ($callApi === 1) {
            // Call the API
        }
    }
}

侦听器应检查重要字段之一是否已更改,如果已更改,则应发送 API 请求(在帐户更新后)。但是,当我更新我的帐户时,我的 API 中的操作似乎仍然使用旧帐户。

然后我尝试die(var_dump($account));里面的callApi函数。结果是 var $account 给了我更新的 实体就像我预期的那样。 BUT函数callApi()里面的数据还没有存入数据库! (我知道这一点是因为 die(var_dump($account)); 中的值与数据库中的值不相等)。所以在那种情况下,我的 API 仍然从数据库中获取旧帐户是正常的。

我不知道为什么会这样,但对我来说,数据似乎是在 postUpdate 函数完全执行后存储的。

我想知道为什么会发生这种情况以及这是否是正常现象。我还想知道如何确保在数据存储到数据库后调用 API。

postUpdate 事件不是在 flush() 之后调用,而是在刷新内部调用。这就是 postFlush 事件存在的原因(即使它不是生命周期回调)。

更多信息请查看官方Doctrine 2 documentation chapter 9. Events