Dor*_*ron 6 object-persistence doctrine-orm
使用doctrine 2.1(以及zend框架1.11,而不是它对这个问题很重要),如何发布持久化和发布更新操作,包括重新保存到数据库?
例如,根据刚生成的主键'id创建唯一令牌,或为上传的图像生成缩略图(实际上不需要重新保存到数据库,但仍然)?
以上实际上是关于两种情况的问题.两种情况都与以下状态有关:
假设我有一个
User实体.当对象在被标记为持久化后被刷新时,它将具有正常的自动生成的mysql id - 意味着正常运行的数字通常从1,2,3等开始.
每个用户都可以上传图像 -他将能够在应用程序中使用 - 它也将在数据库中有记录.所以我有另一个实体叫做Image.每个Image实体还具有自动生成的ID - 与用户ID相同的方法.
现在 - 这是场景:
当用户上传图像时,我想在将图像保存到数据库后立即生成该图像的缩略图.这应该发生在每个新的或更新的图像上.
由于我们试图保持智能,我不希望代码生成缩略图,如下所示:
$ image = new Image();
...
$ entityManager-> persist($ image);
$ entityManager->冲洗();
callToFunctionThatGeneratesThumbnailOnImage($图像);
但是我希望它在对象的持久化上自动发生(好吧,持久化对象的刷新),就像prePersist或者preUpdate方法一样.
由于用户上传了图像,因此他获得了一个图像链接.它可能看起来像:http://www.mysite.com/showImage?id=[IMAGEID].
这允许任何人只需更改此链接中的imageid,并查看其他用户的图像.
所以为了防止这样的事情,我想为每个图像生成一个唯一的标记.因为它实际上并不需要复杂,我想到了使用图像id的md5值和一些盐.
但为此,我需要拥有该图像的ID - 我只有在刷新持久化对象后才会生成 - 然后生成md5,然后再将其保存到数据库中.
了解图像的链接应该是可公开访问的,因此我不能只允许经过身份验证的用户通过某种权限规则查看它们.
您可能已经了解了Doctrine事件.你能做什么:
使用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());
Run Code Online (Sandbox Code Playgroud)
请务必检查例如是否User已有Image,否则如果在事件监听器中调用flush,则可能会陷入无限循环.
当然你也可以让你的User类知道使用内联postPersisteventHandler的图像创建操作并添加@HasLifecycleCallbacks你的映射然后总是在请求结束时刷新,例如在关闭函数中,但在我看来这种东西属于一个独立的倾听者.因人而异.
如果在刷新之前需要实体id,则在创建对象之后,另一种方法是为应用程序中的实体生成id,例如使用uuids.
现在你可以这样做:
class Entity {
public function __construct()
{
$this->id = uuid_create();
}
}
Run Code Online (Sandbox Code Playgroud)
现在你刚刚设置了一个id:
$e = new Entity();
Run Code Online (Sandbox Code Playgroud)
而且您只需要在请求结束时调用EntityManager :: flush
最后,我听了@Arms对这个问题的评论。
我开始使用服务层来做这些事情。
现在,我在服务层中有一个方法来创建图像实体。在调用persist和flush之后,它会调用生成缩略图的方法。
服务层模式是解决此类问题的一个很好的解决方案。