简体   繁体   English

Doctrine:Symfony2 Listener vs inclass Lifecycle回调

[英]Doctrine: Symfony2 Listener vs inclass Lifecycle callbacks

I've been working with an image entity that when persisted, uses internal methods to save/move/delete the image file associated using hook annotations but I feel somewhat like the entity itself should be only relevant getters and setters. 我一直在使用一个图像实体,当持久化时,使用内部方法来保存/移动/删除使用钩子注释关联的图像文件,但我觉得实体本身应该只是相关的getter和setter。

Should I leave the methods in the entity or move them to a listener class? 我应该将方法留在实体中还是将它们移动到监听器类?

The entity has methods that: 该实体具有以下方法:

  • generate unique filename/path 生成唯一的文件名/路径
  • save the image file to disk on persist 将图像文件保存到磁盘上
  • remove the image on cascade remove. 删除级联删除图像。

But I'm unsure I like this being in my entity.. 但我不确定我喜欢这个在我的实体中..

/**
 * @ORM\PostPersist()
 * @ORM\PostUpdate()
 */
public function upload()
{
    if(null === $this->getFile()) {
        return;
    }

    // throws exception on error - stopping persist
    $this->getFile()->move($this->getUploadRootDir(), $this->url);

    if(isset($this->tmp)) {
        unlink($this->getUploadRootDir() . '/'. $this->tmp);
        $this->tmp = null;
    }

    $this->file = null;
}

So I was thinking of moving them into a listener class, using methods like the sample below, however I don't like the idea of it checking every type of entity persist and only caring about the 'image' entities: 所以我正在考虑将它们移动到一个监听器类中,使用类似下面的示例的方法,但是我不喜欢它检查每种类型的实体持续存在的想法,只关心'图像'实体:

public function postPersist(LifecycleEventArgs $args)
{
    $entity = $args->getEntity();
    $entityManager = $args->getEntityManager();

    if ($entity instanceof Image) {
        // ... do something with the Product
    }
}

It really depends on the use case. 这实际上取决于用例。 Quoting from the cookbook on how to handle file uploads : 食谱中引用如何处理文件上传

Using lifecycle callbacks is a limited technique that has some drawbacks. 使用生命周期回调是一种有限的技术,有一些缺点。 If you want to remove the hardcoded DIR reference inside the Document::getUploadRootDir() method, the best way is to start using explicit doctrine listeners. 如果要在Document :: getUploadRootDir()方法中删除硬编码的DIR引用,最好的方法是开始使用显式的doctrine侦听器。 There you will be able to inject kernel parameters such as kernel.root_dir to be able to build absolute paths. 在那里,您将能够注入内核参数,例如kernel.root_dir,以便能够构建绝对路径。

If you want the best of both worlds you could use Entity Listeners . 如果你想要两全其美,你可以使用实体监听器 This listener will only be fired on that single entity instead of listening to all of them: 此侦听器将仅在该单个实体上触发,而不是侦听所有侦听器:

I also recommend looking at the Uploadable Doctrine Extension which should offer all the functionality you need. 我还建议查看可上传的Doctrine扩展 ,它应该提供您需要的所有功能。

It also offers setting a default upload path: http://www.obverse.com/2013/03/the-trick-to-getting-gedmo-uploadable-working-with-sonata-admin/ 它还提供了设置默认上传路径: http//www.obverse.com/2013/03/the-trick-to-getting-gedmo-uploadable-working-with-sonata-admin/

stof_doctrine_extensions:
    default_locale: en_US
    uploadable:
        # Default file path: This is one of the three ways you can configure the path for the Uploadable extension
        default_file_path: %kernel.root_dir%/../web/uploads

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM