Doctrine: Symfony2 监听器 vs 类内生命周期回调

4
我一直在处理一个图像实体,当持久化时,使用内部方法使用钩子注释保存/移动/删除关联的图像文件,但我感觉实体本身应该只有相关的获取器和设置器。
我应该将方法留在实体中还是移动到监听器类中?
该实体具有以下方法:
生成唯一的文件名/路径 在持久化时将图像文件保存到磁盘上 级联删除时删除图像
但是我不确定是否喜欢这些方法存在于我的实体中。
/**
 * @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;
}

我在考虑将它们移动到一个监听器类中,使用以下示例的方法,但我不喜欢它检查每种类型的实体是否持久,并且只关心“image”实体的想法:

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

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

如果 ($entity instanceof Image) { $entity->upload(); } 听起来像是正确的做法。 - axiac
1
这似乎是有悖于生产力的,因为我需要一个监听器和模型上的方法。我想知道哪种方式是正确的,是使用监听器还是实体方法配合钩子注解? - mr12086
2
两种方式都是正确的,选择适合您项目的那个。我引用自文档“生命周期事件监听器比在实体类上定义的简单生命周期回调要强大得多。它们位于实体之上的层次,并且允许您在不同的实体类之间实现可重用的行为。” - axiac
1个回答

0

这真的取决于使用情况。引用自如何处理文件上传的食谱

使用生命周期回调是一种有一些缺点的有限技术。如果您想要删除 Document::getUploadRootDir() 方法中硬编码的 DIR 引用,最好的方法是开始使用显式的 Doctrine 监听器。在那里,您将能够注入内核参数,例如 kernel.root_dir,以便能够构建绝对路径。

如果您想要两全其美,可以使用实体监听器。该监听器仅在单个实体上触发,而不是监听所有实体:

我还建议查看可上传Doctrine扩展,它应该提供您所需的所有功能。

它还提供设置默认上传路径的功能: 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接