Doctrine:Symfony2 Listener vs inclass Lifecycle回调

时间:2015-05-18 12:16:27

标签: php symfony doctrine-orm

我一直在使用图像实体,当持久化时,使用内部方法来保存/移动/删除使用钩子注释关联的图像文件,但我觉得实体本身应该只是相关的getter和setter。

我应该将方法留在实体中还是将它们移到监听器类?

该实体具有以下方法:

  • 生成唯一的文件名/路径
  • 将映像文件保存到磁盘上
  • 删除级联删除图像。

但我不确定我喜欢这个在我的实体中......

/**
 * @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;
}

所以我想把它们变成一个听众课,使用类似下面的示例的方法,但我不喜欢它检查每种类型的实体持续存在的想法,只关心'图像& #39;实体:

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

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

1 个答案:

答案 0 :(得分:0)

这实际上取决于用例。引自cookbook on how to handle file uploads

  

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

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

我还建议您查看应提供所需功能的Uploadable Doctrine Extension

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