我应该如何执行教义 2.1 中涉及重新保存到数据库的持久/更新操作?
使用doctrine 2.1(和zend框架1.11,这对此事并不重要),我如何执行post persist和post update操作,这涉及到重新保存到数据库?
例如,根据刚刚生成的主键 id 创建唯一令牌,或者为上传的图像生成缩略图(实际上不需要重新保存到数据库,但仍然如此)?
编辑 - 让我们解释一下,好吗?
上面实际上是关于两种情况的问题。这两种情况都与以下状态相关:
假设我有一个
User
实体。当对象在被标记为持久化后被刷新时,它将具有 mysql 的正常自动生成的 id - 意味着通常从 1、2、3 等开始的运行号。
每个用户都可以上传一个图像 - 他将能够在应用程序中使用该图像 - 该图像也会在数据库中拥有一条记录。所以我有另一个名为Image
的实体。每个图像
实体还有一个自动生成的ID - 与用户ID相同的方法。
现在 - 以下是场景:
当用户上传图像时,我想在将图像保存到数据库后立即生成该图像的缩略图。每个新的或更新的图像都应该发生这种情况。
<块引用>
由于我们试图保持聪明,我不希望生成缩略图的代码像这样编写:$image = new Image();
...
$entityManager->persist($image);
$entityManager->flush();
callToFunctionThatGeneratesThumbnailOnImage($image);而是我希望它在对象持久化时自动发生(嗯,刷新持久化对象),就像
prePersist
或preUpdate
方法。由于用户上传了图像,因此他获得了该图像的链接。它可能看起来像:
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 calledImage
. EachImage
entity also has an auto-generated id - same methodology as the user id.
Now - here is the scenarios:
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
orpreUpdate
methods.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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能已经了解Doctrine 事件。您可以做什么:
使用
postPersist
事件处理程序。该事件发生在数据库插入之后,因此自动生成的 ID 可用。EventManager
类可以帮助您完成此操作:请务必检查例如
User
是否已经有Image
,否则如果您在事件监听器,你可能会陷入无限循环。当然,您也可以使用内联的 postPersist 事件处理程序让您的 User 类了解图像创建操作,并在映射中添加 @HasLifecycleCallbacks ,然后总是在请求结束时刷新,例如在关闭函数中,但在我看来,这种东西属于单独的侦听器。 YMMV。
如果您在创建对象后刷新之前需要实体 id,另一种方法是为应用程序中的实体生成 id,例如使用 uuid。
现在你可以做类似的事情:
现在你已经设置了一个 id,当你这样做时:
你只需要在请求结束时调用 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:Be sure to check e. g. if the
User
already has anImage
, 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 inlinepostPersist
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:
Now you have an id already set when you just do:
And you only need to call EntityManager::flush at the end of the request
最后,我听了@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.