Symfony HttpFoundation已上传文件“由于未知错误而未上传”当使用Doctrine DataFixtures [英] Symfony HttpFoundation UploadedFile "not uploaded due to unknown error" when using Doctrine DataFixtures

查看:251
本文介绍了Symfony HttpFoundation已上传文件“由于未知错误而未上传”当使用Doctrine DataFixtures的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用我的附件实体,基于食谱烹饪如何处理使用Doctrine的文件上传在Symfony 2.3中。

I've been using my Attachment entity based on the cookbook recipie How To Handle File Uploads With Doctrine in Symfony 2.3.

即使在功能测试中也可以正常工作。但是与Doctrine DataFixtures一起使用会导致我的问题。

It works well, even in functional tests. However using it with Doctrine DataFixtures is causing me problems.


[Symfony\Component\HttpFoundation\File \Exception\FileException]

由于未知错误,文件o-rly-copy.jpg未上传。

这没有帮助,但是我没有运行 php app / console doctrine:fixtures:load -v 来显示一个堆栈跟踪,并且看起来不是在持久化方法上抛出异常,而是在 $ manager-> flush()

This was not helpful, however I did run php app/console doctrine:fixtures:load -v to bring up a stack trace and it appears the exception is thrown not on the persisting method, but on $manager->flush()

Attachment :: setFile()需要一个 UploadedFile 的实例,所以我想知道有没有办法

Attachment::setFile() requires an instance of UploadedFile so I wonder if there is a way round that.

似乎错误发生在 Symfony\Component\HttpFoundation\File\UploadedFile

return $this->test ? $isOk : $isOk && is_uploaded_file($this->getPathname())

的条件is_uploaded_file ()返回 false ,因为文件已经在服务器上。

The condition for is_uploaded_file() returns false because the file was already on the server.

<?php

/**
 * Prepopulate the database with image attachments.
 */
final class AttachmentFixtures extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
    private static $imageData = array(
        array(
            'name' => "O RLY?",
            'file' => "o-rly",
            'type' => "jpg",
        ),
        //...
    );

    public function getPathToImages()
    {
        return $this->container->get('kernel')->getRootDir() . '/../src/Acme/DemoBundle/Resources/public/default/images';
    }

    public function getPathToUploads()
    {
        return $this->container->get('kernel')->getRootDir() . '/../web/uploads/fixtures';
    }

    /**
     * {@inheritDoc}
     */
    public function load(ObjectManager $manager)
    {
        $imageReferences = array();
        $filesystem = $this->container->get('filesystem');

        foreach (self::$imageData as $image) {
            $imageFilename         = sprintf('%s.%s',      $image['file'], $image['type']);
            $copiedImageFilename   = sprintf('%s-copy.%s', $image['file'], $image['type']);

            $pathToImageFile = sprintf('%s/%s', $this->getPathToImages(), $imageFilename);

            try {
                $filesystem->copy($pathToImageFile, $pathToCopiedFile = sprintf('%s/%s', $this->getPathToUploads(), $copiedImageFilename));
                $filesystem->chmod($pathToCopiedFile, 0664);
            } catch (IOException $e) {
                $this->container->get('logger')->err("An error occurred while copying the file or changing permissions.");
            }

            $imageFile = new UploadedFile(
                $pathToCopiedFile,                                              // The full temporary path to the file
                $copiedImageFilename,                                           // The original file name
                'image/' . 'jpg' === $image['type'] ? 'jpeg' : $image['type'],  // Mime type - The type of the file as would be provided by PHP
                filesize($pathToCopiedFile),
                null,
                null,
                true
            );

            $imageAttachment = new Attachment();

            $imageAttachment->setName($image['name']);
            $imageAttachment->setFile($imageFile);

            // Populate a reference array for later use
            $imageReferences['attachment-'.$image['file']] = $imageAttachment;

            $manager->persist($imageAttachment);
        }

        $manager->flush(); // <-- Exception throw here


        // Create references for each image to be used by other entities that
        // maintain a relationship with that image.
        foreach ($imageReferences as $referenceName => $image) {
            $this->addReference($referenceName, $image);
        }
    }
}


推荐答案

感谢stof ,解决方案是使附件:: setFile()(或 Document :: setFile()如果使用菜谱示例)提示 UploadedFile 的父类, Symfony\Component\HttpFoundation\File\File ,在fixtures类中,创建一个新的实例并将其传递给setFile方法

Thanks to stof, the solution is to make Attachment::setFile() (or Document::setFile() if using the cookbook example) hint for an instance of UploadedFile's parent class, Symfony\Component\HttpFoundation\File\File, and in the fixtures class, create a new instance and pass it to the setFile method

Attachment.php

<?php

namespace Acme\DemoBundle\Entity;

use Symfony\Component\HttpFoundation\File\File;
//...

class Attachment
{
    /**
     * Sets file.
     *
     * @param File $file
     */
    public function setFile(File $file = null)
    {
        $this->file = $file;
        // check if we have an old image path
        if (isset($this->path)) {
            // store the old name to delete after the update
            $this->temp = $this->path;
            $this->path = null;
        } else {
            $this->path = 'initial';
        }
    }

    //...
}

AttachmentFixtures.php

<?php

namespace Acme\DemoBundle\DataFixtures\ORM;

use Symfony\Component\HttpFoundation\File\File;
//...

class AttachmentFixtures //...
{
    //...

    public function load(ObjectManager $manager)
    {
        //...
        $imageFile = new File($pathToCopiedFile);

        $imageAttachment = new Attachment();

        $imageAttachment->setFile($imageFile);
        //...
    }
}

这篇关于Symfony HttpFoundation已上传文件“由于未知错误而未上传”当使用Doctrine DataFixtures的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆