如何正确使用 Doctrine 中的 postUpdate、postRemove、postPersist?

How to properly use postUpdate, postRemove, postPersist in Doctrine?

文档说:https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/events.html#postupdate-postremove-postpersist

The three post events are called inside EntityManager#flush(). Changes in here are not relevant to the persistence in the database, but you can use these events to alter non-persistable items, like non-mapped fields, logging or even associated classes that are not directly mapped by Doctrine.

让我们假设我有一个 Image 实体:

<?php
/**
 * @ORM\Entity
 */
class Image
{
    /**
     * @var int|null
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private ?int $id = null;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private string $path;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private string $status = 'RECEIVED';
}

刷新 Image 实体后,我想将相应的文件上传到 FTP 服务器,因此我在 postPersist 事件中执行此操作。

但是如果 FTP 上传失败,我想将 Image 的状态更改为 FTP_ERROR。

<?php
public function postPersist(Image $image, LifecycleEventArgs $event)
{
    $em = $event->getEntityManager();
    try {
        $this->someService->uploadToFtp($image);
    } catch (Exception $e) {
        $image->setStatus('FTP_ERROR');
        $em->persist($image);
        $em->flush();
    }
}

它确实有效,但正如文档所述,这不是一个好方法。

我看过这个 post: 上面写着:

@iiirxs:

It is ok to call flush() on a PostPersist lifecycle callback in order to change a mapped property of your entity.

那么怎么做呢? @iiirxs 和文档说了两件事。

在 postPersist 等事件上下载内容的最佳方法是使用 https://symfony.com/doc/current/components/messenger.html

因此,您可以为文件上传创建异步任务,Symfony Messenger 将能够处理错误并在失败时自动重试,您还可以在单​​独的进程中更新它、状态等,它不会取决于具体的学说案例,例如您问题中的案例。