如何在doctrine 2.1中发布持久化/更新操作,包括重新保存到数据库?

时间:2011-09-12 14:46:38

标签: doctrine-orm object-persistence

使用doctrine 2.1(以及zend框架1.11,并不重要的是这个问题),如何发布持久化和发布更新操作,包括重新保存到数据库?

例如,根据刚生成的主键'id创建唯一令牌,或者为上传的图像生成缩略图(实际上不需要重新保存到数据库,但仍然)?


编辑 - 让我们解释一下,不管吗?

以上实际上是关于两种情况的问题。两种情况都与以下状态有关:

  

假设我有一个 User 实体。当对象在被标记为持久化后被刷新时,它将具有正常的自动生成的mysql id - 意味着正常运行的数字通常从1,2,3等开始。
  每个用户都可以上传一张图片 - 他可以在应用程序中使用 - 这也将在数据库中有一条记录。所以我有另一个名为 Image 的实体。每个 Image 实体也有一个自动生成的ID - 与用户ID相同的方法。

现在 - 这是场景:

  1. 当用户上传图片时,我想在将图片保存到数据库后立即生成该图片的缩略图。这应该发生在每个新的或更新的图像上 由于我们试图保持智能,我不希望代码生成缩略图,如下所示:

      

    $ image = new Image();
      ...
      $ entityManager->坚持($图像);
      $ entityManager->冲洗();
      callToFunctionThatGeneratesThumbnailOnImage($图像);

    但我希望它在对象的持久性上自动发生(好吧,冲洗持久化对象),如prePersistpreUpdate方法。

  2. 由于用户上传了图片,因此他获得了一个图片链接。它可能看起来像:http://www.mysite.com/showImage?id=[IMAGEID] 这允许任何人只需更改此链接中的imageid,并查看其他用户的图像 所以为了防止这样的事情,我想为每个图像生成一个唯一的标记。因为它不需要复杂,我想到使用图像id的md5值,加上一些盐 但为此,我需要拥有该图像的ID - 我只有在刷新持久化对象后才会生成 - 然后生成md5,然后再将其保存到数据库。

  3. 了解图像的链接应该是可公开访问的,因此我不能仅允许经过身份验证的用户通过某种权限规则查看它们。

2 个答案:

答案 0 :(得分:7)

您可能已经知道Doctrine events了。你能做什么:

使用postPersist事件处理程序。那个在DB插入之后发生,因此自动生成的id可用。

EventManager课程可以帮助您:

class MyEventListener
{
    public function postPersist(LifecycleEventArgs $eventArgs)
    {
        // in a listener you have the entity instance and the 
        // EntityManager available via the event arguments
        $entity = $eventArgs->getEntity();
        $em = $eventArgs->getEntityManager();

        if ($entity instanceof User) {
            // do some stuff
        }

    }
}

$eventManager = $em->getEventManager():
$eventManager->addEventListener(Events::postPersist, new MyEventListener());

务必检查e。 G。如果User已经有Image,否则如果在事件监听器中调用flush,则可能会陷入无限循环。

当然,您也可以使User类通过内联postPersist eventHandler了解该图像创建操作,并在映射中添加@HasLifecycleCallbacks,然后始终在要求e。 G。在关机功能,但在我看来这种东西属于一个单独的监听器。因人而异。

如果在刷新之前需要实体ID,则在创建对象之后,另一种方法是为应用程序中的实体生成id,例如: G。使用uuids

现在您可以执行以下操作:

class Entity {
    public function __construct()
    {
        $this->id = uuid_create();
    }
}

现在你刚刚设置了一个id:

$e = new Entity();

您只需要在请求结束时调用EntityManager :: flush

答案 1 :(得分:2)

最后,我听了评论这个问题的@Arms 我开始使用服务层来做这些事情 所以现在,我在服务层中有一个创建Image实体的方法。在调用persist和flush之后,它调用生成缩略图的方法。

服务层模式是这类事情的一个很好的解决方案。