通过VichUploaderBundle上传文件时的ContextErrorException

时间:2014-10-11 10:04:10

标签: symfony file-upload vichuploaderbundle

我正在尝试上传基于VichUploaderBundle的文件。 我在实现它时遇到了这个错误:

ContextErrorException: Catchable Fatal Error: Argument 1 passed to Minn\AdsBundle\Entity\MotorsAdsFile::setFile() must be an instance of Symfony\Component\HttpFoundation\File\File, string given,... 

我知道问题是方法setFile()中给定参数的Class。但是,我在github的文档中找到了这个。

所以,这就是我所做的&我希望我能解决问题!

捆绑包的配置

vich_uploader:
    db_driver: orm # or mongodb or propel or phpcr
    mappings:
        motors_files:
            uri_prefix:         /files/motors
            upload_destination: %kernel.root_dir%/../web/files/motors
            namer: vich_uploader.namer_origname
            delete_on_remove: true

我的文件实体的定义

<?php

namespace Minn\AdsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity
 * @Vich\Uploadable
 */
class MotorsAdsFile {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @Assert\File(
     *     maxSize="5M",
     *     mimeTypes={"image/png", "image/jpeg"}
     * )
     * @Vich\UploadableField(mapping="motors_files", fileNameProperty="file")
     * note: This is not a mapped field of entity metadata, just a simple property.
     * @var File $file
     */
    protected $file;

    /**
     * @ORM\Column(type="string", length=255, name="name")
     * @var string $name
     */
    protected $name;

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
     */
    public function setFile(File $file) {
        $this->file = $file;
    }

    /**
     * @return File
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * @param string $name
     */
    public function setName($name) {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }

}

表单的Twig部分

<form action="{{ path('minn_ads_motors_test6') }}" {{ form_enctype(form) }} method="POST">
    {{ form_widget(form) }}
    <div>
        <input type="submit" value="do it with VICH" />
    </div>
</form>

我的操作()在我的控制器中

public function motorstest6Action(Request $request) {
    $document = new MotorsAdsFile();
    $form = $this->createFormBuilder($document)
            ->add('name')
            ->add('file')
            ->getForm();

    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($document);
        $em->flush();

        return $this->redirect($this->generateUrl('minn_ads_default_index'));
    }
    return $this->render('MinnAdsBundle:Motors:adddoc1.html.twig', array(
                'form' => $form->createView()));
}

2 个答案:

答案 0 :(得分:2)

您的实体未正确配置。为了使这个包工作,实体必须有两个字段来表示文件:一个用于存储File对象(未由doctrine映射),另一个用于存储其名称(作为字符串,由doctrine映射) )。 您的实体只有第一个字段。

以下是您应该如何定义它:

<?php

namespace Minn\AdsBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * @ORM\Entity
 * @Vich\Uploadable
 */
class MotorsAdsFile {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    public $id;

    /**
     * @Assert\File(
     *     maxSize="5M",
     *     mimeTypes={"image/png", "image/jpeg"}
     * )
     * @Vich\UploadableField(mapping="motors_files", fileNameProperty="filename")
     * note: This is not a mapped field of entity metadata, just a simple property.
     * @var File $file
     */
    protected $file;

    /**
     * @ORM\Column(type="string", length=255, name="filename")
     * @var string $filename
     */
    protected $filename;

    /**
     * @ORM\Column(type="string", length=255, name="name")
     * @var string $name
     */
    protected $name;

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
     */
    public function setFile(File $file) {
        $this->file = $file;
    }

    /**
     * @return File
     */
    public function getFile() {
        return $this->file;
    }

    /**
     * @param string $filenname
     */
    public function setFilename($filename) {
        $this->filename = $filename;
    }

    /**
     * @return string
     */
    public function getFilename() {
        return $this->file;
    }

    /**
     * @param string $name
     */
    public function setName($name) {
        $this->name = $name;
    }

    /**
     * @return string
     */
    public function getName() {
        return $this->name;
    }
}

请注意新的filename字段以及filenameProperty注释中UploadableField选项的新值。

答案 1 :(得分:0)

  

你完成了!现在创建一个带有imageFile字段的表单,该字段使用   文件类型。

https://github.com/dustin10/VichUploaderBundle/blob/master/Resources/doc/usage.md#that-was-it

所以你可能想试试这个

        ->add('file', 'file')

而不是

        ->add('file')

由于您的字段未映射,因此默认情况下FormBuilder可能会将其设置为字符串。