我应该如何执行教义 2.1 中涉及重新保存到数据库的持久/更新操作?

发布于 2024-12-04 02:13:04 字数 1306 浏览 0 评论 0原文

使用doctrine 2.1(和zend框架1.11,这对此事并不重要),我如何执行post persist和post update操作,这涉及到重新保存到数据库?

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


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

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

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

现在 - 以下是场景:

  1. 当用户上传图像时,我想在将图像保存到数据库后立即生成该图像的缩略图。每个新的或更新的图像都应该发生这种情况。
    由于我们试图保持聪明,我不希望生成缩略图的代码像这样编写:

    <块引用>

    $image = new Image();
    ...
    $entityManager->persist($image);
    $entityManager->flush();
    callToFunctionThatGeneratesThumbnailOnImage($image);

    而是我希望它在对象持久化时自动发生(嗯,刷新持久化对象),就像 prePersistpreUpdate 方法。

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

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

Using doctrine 2.1 (and zend framework 1.11, not that it matters for this matter), how can I do post persist and post update actions, that involves re-saving to the db?

For example, creating a unique token based on the just generated primary key' id, or generating a thumbnail for an uploaded image (which actually doesn't require re-saving to the db, but still) ?


EDIT - let's explain, shall we ?

The above is actually a question regarding two scenarios. Both scenarios relate to the following state:

Let's say I have a User entity. When the object is flushed after it has been marked to be persisted, it'll have the normal auto-generated id of mysql - meaning running numbers normally beginning at 1, 2, 3, etc..
Each user can upload an image - which he will be able to use in the application - which will have a record in the db as well. So I have another entity called Image. Each Image entity also has an auto-generated id - same methodology as the user id.

Now - here is the scenarios:

  1. When a user uploads an image, I want to generate a thumbnail for that image right after it is saved to the db. This should happen for every new or updated image.
    Since we're trying to stay smart, I don't want the code to generate the thumbnail to be written like this:

    $image = new Image();
    ...
    $entityManager->persist($image);
    $entityManager->flush();
    callToFunctionThatGeneratesThumbnailOnImage($image);

    but rather I want it to occur automatically on the persisting of the object (well, flush of the persisted object), like the prePersist or preUpdate methods.

  2. Since the user uploaded an image, he get's a link to it. It will probably look something like: http://www.mysite.com/showImage?id=[IMAGEID].
    This allows anyone to just change the imageid in this link, and see other user's images.
    So in order to prevent such a thing, I want to generate a unique token for every image. Since it doesn't really need to be sophisticated, I thought about using the md5 value of the image id, with some salt.
    But for that, I need to have the id of that image - which I'll only have after flushing the persisted object - then generate the md5, and then saving it again to the db.

Understand that the links for the images are supposed to be publicly accessible so I can't just allow an authenticated user to view them by some kind of permission rules.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情场扛把子 2024-12-11 02:13:05

您可能已经了解Doctrine 事件。您可以做什么:

使用 postPersist 事件处理程序。该事件发生在数据库插入之后,因此自动生成的 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());

请务必检查例如 User 是否已经有 Image,否则如果您在事件监听器,你可能会陷入无限循环。

当然,您也可以使用内联的 postPersist 事件处理程序让您的 User 类了解图像创建操作,并在映射中添加 @HasLifecycleCallbacks ,然后总是在请求结束时刷新,例如在关闭函数中,但在我看来,这种东西属于单独的侦听器。 YMMV。

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

现在你可以做类似的事情:

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

现在你已经设置了一个 id,当你这样做时:

$e = new Entity();

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

You probably know already about Doctrine events. What you could do:

Use the postPersist event handler. That one occurs after the DB insert, so the auto generated ids are available.

The EventManager class can help you with this:

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());

Be sure to check e. g. if the User already has an Image, otherwise if you call flush in the event listener, you might be caught in an endless loop.

Of course you could also make your User class aware of that image creation operation with an inline postPersist eventHandler and add @HasLifecycleCallbacks in your mapping and then always flush at the end of the request e. g. in a shutdown function, but in my opinion this kind of stuff belongs in a separate listener. YMMV.

If you need the entity id before flushing, just after creating the object, another approach is to generate the ids for the entities within your application, e. g. using uuids.

Now you can do something like:

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

Now you have an id already set when you just do:

$e = new Entity();

And you only need to call EntityManager::flush at the end of the request

罗罗贝儿 2024-12-11 02:13:05

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

服务层模式是解决此类问题的一个很好的解决方案。

In the end, I listened to @Arms who commented on the question.
I started using a service layer for doing such things.
So now, I have a method in the service layer which creates the Image entity. After it calls the persist and flush, it calls the method that generates the thumbnail.

The Service Layer pattern is a good solution for such things.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文