Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/symfony/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Symfony 如何从实体内部获取web目录路径?_Symfony_Symfony 2.1 - Fatal编程技术网

Symfony 如何从实体内部获取web目录路径?

Symfony 如何从实体内部获取web目录路径?,symfony,symfony-2.1,Symfony,Symfony 2.1,我研究了,我不想硬编码\uuuuuu DIR\uuuu./../../../../../../web/'.$this->getUploadDir()路径,因为将来我可能会更改web/目录。如何做到更灵活?我发现,但它没有回答如何从实体内部更灵活地执行此操作的问题此处不应将实体类用作表单模型。这根本不适合那个工作。如果实体具有path属性,则它只能存储以下有效值:null(如果缺少文件)和表示文件路径的字符串 创建一个单独的类,它将成为表单的模型: class MyFormModel {

我研究了,我不想硬编码
\uuuuuu DIR\uuuu./../../../../../../web/'.$this->getUploadDir()路径,因为将来我可能会更改
web/
目录。如何做到更灵活?我发现,但它没有回答如何从实体内部更灵活地执行此操作的问题

此处不应将实体类用作表单模型。这根本不适合那个工作。如果实体具有
path
属性,则它只能存储以下有效值:
null
(如果缺少文件)和表示文件路径的字符串

  • 创建一个单独的类,它将成为表单的模型:

    class MyFormModel {
         /** @Assert\File */
         private $file;
    
         /** @Assert\Valid */
         private $entity;
    
         // constructor, getters, setters, other methods
    }
    
  • 在表单处理程序(通过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访问任何依赖项/属性(包括上传目录的路径)



    你链接的教程很有用,但它是一个糟糕设计的例子。实体不应知道文件上载。

    您可以在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
    ...
    

    我通过创建一个抽象类来处理这个问题,如果实体按照Symfony文档中的描述处理文件上传,则可以扩展这个抽象类。我创建了文件数组,以便可以在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();
    }
    

    要从控制器外部访问根目录,只需在服务配置中插入“%kernel.root\u dir%”作为参数

    service_name:
        class: Namespace\Bundle\etc
        arguments: ['%kernel.root_dir%']
    
    然后可以在类构造函数中获取web根:

    public function __construct($rootDir)
    {
        $this->webRoot = realpath($rootDir . '/../web');
    }
    

    我明白了。谢谢但是如何使用生命周期回调来管理代码中文件的删除?根据以前的经验,我建议您也存储绝对路径(或至少相对于webroot路径)。创建一个监听器,订阅
    预删除
    (或
    预删除
    )事件(请参阅)并在那里取消文件链接。如何在实体中获取它?您的实体不负责知道文档存储在哪里。您可以将此责任转移给您的管理员。或者您可以向entityHm添加路径属性,我看到您使用了
    \uuuuu DIR\uuuu。“/../../../../web/”
    也是,但我的问题是如何避免它。我不确定是否有。看来我能做的就是在一个地方定义它,明白了。谢谢你的解决方案,汤姆