4

我研究了如何使用 Doctrine 处理文件上传,我不想硬编码__DIR__.'/../../../../web/'.$this->getUploadDir();路径,因为将来我可能会更改web/目录。怎么做更灵活?我发现了这个,但它没有回答如何从实体内部更灵活地做到这一点的问题

4

4 回答 4

6

您不应该在这里使用实体类作为表单模型。它根本不适合那个工作。如果实体具有该path属性,则它可以存储的唯一有效值是:(null如果缺少文件)和表示文件路径的字符串。

  1. 创建一个单独的类,这将是您表单的模型:

    class MyFormModel {
         /** @Assert\File */
         private $file;
    
         /** @Assert\Valid */
         private $entity;
    
         // constructor, getters, setters, other methods
    }
    
  2. 在您的表单处理程序(通过 DIC 配置的单独对象;推荐)或控制器中:

    ...
    if ($form->isValid()) {
        /** @var \Symfony\Component\HttpFoundation\File\UploadedFile */
        $file   = $form->getData()->getFile();
    
        /** @var \Your\Entity\Class */
        $entity = $form->getData()->getEntity();
    
        // move the file
        // $path = '/path/to/the/moved/file';
    
        $entity->setPath($path);
    
        $someEntityManager->persist($entity);
    
        return ...;
    }
    ...
    

在表单处理程序/控制器中,您可以从 DIC 访问任何依赖项/属性(包括上传目录的路径)。


您链接的教程有效,但它是糟糕设计的一个例子。实体应该知道文件上传。

于 2012-10-15T10:42:09.400 回答
1

要从控制器外部访问根目录,您只需在服务配置中注入 '%kernel.root_dir%' 作为参数即可。

service_name:
    class: Namespace\Bundle\etc
    arguments: ['%kernel.root_dir%']

然后你可以在类构造函数中获取web根:

public function __construct($rootDir)
{
    $this->webRoot = realpath($rootDir . '/../web');
}
于 2014-01-15T16:50:57.003 回答
-1

您可以在 parameters.yml 中使用变量。像这样,您可以根据需要更改路径。

例如 :

# app/config/parameters.yml
# Upload directories
upload_avatar_dir:        /uploads/avatars
upload_content_dir:       /uploads/content
upload_product_offer_dir: /uploads/product-offer
...
于 2012-10-15T14:45:26.930 回答
-1

我通过创建一个抽象类来处理这个问题,如果实体按照 Symfony 文档中的描述处理文件上传,它们可以扩展该类。我创建了 files 数组,以便可以在 set 方法中创建现有文件路径的副本,以便在成功更新或删除时将其从文件系统中删除,而无需在实体中定义任何其他属性。

use Symfony\Component\HttpFoundation\File\File;

abstract class FileUploadEntity
{
    private $files;

    public function __set($name, File $value)
    {
        $this->files[$name] = $value;
    }

    public function __get($name)
    {
        if (!is_array($this->files)) $this->files = array();

        if (!array_key_exists($name, $this->files)) {
            return null;
        }
        return $this->files[$name];
    }

    public function getUploadRootDirectory()
    {
        return $this->getWebDirectory() . $this->getUploadDirectory();
    }

    public function getWebDirectory()
    {
        return __DIR__ . "/../../../../web/";
    }

    public function getUploadDirectory()
    {
        $year = date("Y");
        $month= date("m");

        return "images/uploads/$year/$month/";
    }

    public function getEncodedFilename($name)
    {
        return sha1($name . uniqid(mt_rand(), true));
    }

    // this should be a PrePersist method
    abstract public function processImages();

    // This should be defined as a Doctrine PreUpdate Method
    abstract public function checkImages();

    // this should be a PostPersist method
    abstract public function upload();

    // this should be a PostUpdate method and delete old files
    abstract public function checkUpload();

    // This should be a PostRemove method and delete files
    abstract public function deleteFile();
}
于 2013-08-30T03:23:35.210 回答