首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上传Symfony2中的文件:可捕获的致命错误:传递给

上传Symfony2中的文件:可捕获的致命错误:传递给
EN

Stack Overflow用户
提问于 2014-12-29 12:27:53
回答 1查看 1.5K关注 0票数 1

我使用Symfony2和wamp服务器。我尝试在之后实现上传方法。

我有两个实体DocumentsEnsemble.phpEnsembles.php。DocumentsEnsembles是I存储上传文件的实体,用于1集成(图像、文档、pdf等)。集成可以有0或多个文档,而文档可以属于0或1单个集成。

这是我的实体代码,名为Ensembles.php

代码语言:javascript
复制
namespace MySpace\DatabaseBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * Ensembles
 *
 * @ORM\Table(name="ensembles")
 * @ORM\Entity
 */
class Ensembles
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
    * @var string
    *
    * @ORM\Column(name="nom", type="string", length=150, nullable=false)
    */
    private $nom;

    /**
    * @ORM\ManyToOne(targetEntity="Documentsensemble", inversedBy="file")
    * @ORM\JoinColumn(name="documentsensemble_id", referencedColumnName="id", nullable=true)
    */
    private $documentsensemble;

   //the getters and setters

  //implement Upload method
public function preUpload()
    {
        if (null !== $this->file) {
            $this->path = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();
        }
    }

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {
        if (null === $this->file) {
            return;
        }
        $this->file->move($this->getUploadRootDir(), $this->path);

        unset($this->file);
    }

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        if ($file = $this->getAbsolutePath()) {
            unlink($file);
        }
    }

我想实现上传的方法,就像你可以在成群看到。这是名为DocumentsEnsemble的DocumentsEnsembles.php实体

代码语言:javascript
复制
namespace MySpace\DatabaseBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * Documentsensemble
 *
 * @ORM\Table(name="documentsensemble")
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class Documentsensemble
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false)
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\NotBlank
 */
public $nom;

/**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    public $path; //La propriété path stocke le chemin relatif du fichier et est persistée dans la base de données

    public function getAbsolutePath()
    {
        return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->path;
    }

    public function getWebPath()
    {
        return null === $this->path ? null : $this->getUploadDir().'/'.$this->path;
    }

    protected function getUploadRootDir()
    {
        return __DIR__.'src/MySpace/WelcomeBundle/Ressources/public/image/uploadEnsembles'.$this->getUploadDir();
    }

    protected function getUploadDir()
    {
        return 'uploads/documents';
    }

    /**
     * @Assert\File(maxSize="4M")
     * @ORM\OneToMany(targetEntity="Ensembles", mappedBy="documentsensemble")
     */
    public $file;

   // the getters and setters

在一个使用post方法的表单中,我可以在我的集合实体中添加一个集合。此表单包含要上载属于集合的文件的输入文件。我使用一个名为EnsemblesType.php的Doctrine生成的表单,这是用于:

代码语言:javascript
复制
namespace MySpace\DatabaseBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class EnsemblesType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('referenceclient')
            ->add('nom')
            ->add('voie')
            ->add('numerovoie')
            ->add('codepostal')
            ->add('commune')
            ->add('dateactivation','date', array(
                    'widget' => 'single_text',
                    'format' => 'yyyy-MM-dd',
                    'attr' => array('class' => 'datepicker')
                    ))
            ->add('datedesactivation', 'date', array(
                    'widget' => 'single_text',
                    'format' => 'yyyy-MM-dd',
                    'attr' => array('class' => 'datepicker')
                    ))
            ->add('documentsensemble', 'file')
            ->add('parcsimmobilier')
            ->add('systemes')
        ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MySpace\DatabaseBundle\Entity\Ensembles'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'MySpace_databasebundle_ensembles';
    }
}

这是带有post方法的表单的addEnsembles.html.twig

代码语言:javascript
复制
<form action="{{ path('ajouterEnsembles_process') }}" method="post" {{ form_enctype(formEnsemble) }}>
  {{ form_errors(formEnsemble) }}   
  <div>
    {{ form_label(formEnsemble.nom, "Nom de l'ensemble:", {'label_attr': {'class': 'control-label'}}) }}
    {{ form_errors(formEnsemble.nom) }}
    <div>
      {{ form_widget(formEnsemble.nom, {'attr': {'class': 'form-control'}}) }}
    </div>
  </div>
  <br>
  {# Upload #}
  <div class="container">
    <div class="row col-md-12">
      <div class="row col-md-9">
       {{ form_label(formEnsemble.documentsensemble, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
        <div>
         {{ form_widget(formEnsemble.documentsensemble) }}
        </div>
      </div>
      <br>
      {# validation #}
      <div class="row col-md-3">
        <input type="submit" value="Ajouter" class="btn btn-success"/>
      </div>
    </div>
  </div>
</form>

当我提交我的表单时,我有以下错误:

可捕获的致命错误:传递给MySpace\DatabaseBundle\Entity\Ensembles::setDocumentsensemble()的参数1必须是给定的Symfony\Component\HttpFoundation\File\UploadedFile实例的实例,在第438行的C:\wamp\www\BitbucketRepository\repos\SymfonyGirusMySpace\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php中调用,在C:\wamp\www\BitbucketRepository\repos\SymfonyGirusMySpace\src\MySpace\DatabaseBundle\Entity\Ensembles.php第411行中定义。

有人能解释我才能找到正确的解决方案吗?我对上传文件的方法做得对吗?

这是我的控制器方法,用于添加一个包含上传文件的集合:

代码语言:javascript
复制
public function addEnsemblesAction() {

        $em=$this->getDoctrine()->getManager();
        $ensemble = new Ensembles;
        $formEnsemble=$this->createForm(new EnsemblesType(), $ensemble);

        $request = $this->getRequest();

            if ($request->isMethod('POST') | ($formEnsemble->isValid())) {

                    $formEnsemble->bind($request);
                    $ensemble = $formEnsemble->getData();

                    $em->persist($ensemble);
                    $em->flush();

                    return $this->redirect($this->generateUrl('showEnsembles'));
                }

            else {
                    return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:addrEnsembles.html.twig', array('formEnsemble' => $formEnsemble->createView() ));
                 }

}

更新问题以求解决

感谢Abdallah Arffak的回答和评论

事实上,我改变了我的两个提子之间的关系。实际上,上传方法必须在Documentsensemble.php中。

这是Ensembles.php的代码:

代码语言:javascript
复制
namespace MySpace\DatabaseBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * Ensembles
 *
 * @ORM\Table(name="ensembles")
 * @ORM\Entity
 */
class Ensembles
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
    * @var string
    *
    * @ORM\Column(name="nom", type="string", length=150, nullable=false)
    */
    private $nom;

    // The getters and setters

现在使用upload方法(回调等.)编写Documentsensembles.php代码:

代码语言:javascript
复制
namespace MySpace\DatabaseBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;

/**
 * Documentsensemble
 *
 * @ORM\HasLifecycleCallbacks
 * @ORM\Table(name="documentsensemble", indexes={@ORM\Index(name="IDX_674FC05E5BA556D3", columns={"ensembles_id"})})
 * @ORM\Entity
 */
class Documentsensemble
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="nom", type="string", length=255, nullable=false)
     * @Assert\NotBlank
     */
    private $nom;

    /**
     * @var string
     *
     * @ORM\Column(name="path", type="string", length=255, nullable=true)
     */
    private $path; //stocke le chemin relatif du fichier et est persistée dans la base de données


    /**
    * @Assert\File(maxSize="6000000")
    */
    public $file;

    // UPLOAD
        public function getWebPath()
        {
            return null === $this->path ? null : $this->getUploadDir().'/'.$this->path;
        }

        protected function getUploadRootDir()
        {
            // le chemin absolu du répertoire où les documents uploadés doivent être sauvegardés
            return __DIR__.'/../../../../MySpace/'.$this->getUploadDir();
        }

        protected function getUploadDir()
        {
            // on se débarrasse de « __DIR__ » afin de ne pas avoir de problème lorsqu'on affiche le document/image dans la vue.
            return 'uploads/documentsEnsemble';
        }

        // propriété utilisé temporairement pour la suppression
        private $filenameForRemove;

        /**
         * @ORM\PrePersist()
         * @ORM\PreUpdate()
         */
        public function preUpload()
        {
            if (null !== $this->file) {
                $this->path = $this->file->guessExtension();
            }
        }

        /**
         * @ORM\PostPersist()
         * @ORM\PostUpdate()
         */
        public function upload()
        {
            if (null === $this->file) {
                return;
            }

            // lancer une exception ici si le fichier ne peut pas être déplacé afin que l'entité ne soit pas persistée dans la base de données comme le fait la méthode move() de UploadedFile
            $this->file->move($this->getUploadRootDir(), $this->nom.'.'.$this->file->guessExtension());

            unset($this->file);
        }

        /**
         * @ORM\PreRemove()
         */
        public function storeFilenameForRemove()
        {
            $this->filenameForRemove = $this->getAbsolutePath();
        }

        /**
         * @ORM\PostRemove()
         */
        public function removeUpload()
        {
            if ($this->filenameForRemove) {
                unlink($this->filenameForRemove);
            }
        }

        public function getAbsolutePath()
        {
            return null === $this->path ? null : $this->getUploadRootDir().'/'.$this->nom.'.'.$this->path = $this->file->guessExtension();
        }
        // The getters and the setters

现在是控制器的代码:

代码语言:javascript
复制
public function uploadAction() {

        $message = "Infos: aucun documents uploadé présent pour le moment";
        $em=$this->getDoctrine()->getManager();
        $documentsensemble = $em->getRepository('MySpaceDatabaseBundle:Documentsensemble');

        $documentsensemble = new Documentsensemble();
        $formUpload = $this->createForm(new DocumentsensembleType(), $documentsensemble);


        $requestUpload = $this->getRequest();

        //instruction if à plusieurs conditions: ici si la method est POST et si le formulaire est valide
        if ($requestUpload->isMethod('POST') | ($formUpload->isValid())) {

                $formUpload->bind($requestUpload);
                $documentsensemble = $formUpload->getData();
                //$documentsensemble->upload();
                //Cette ligtne est commenté car nous utilisons les callbacks pour la méthode Upload de Symfony

                $em->persist($documentsensemble);
                $em->flush();

                return $this->redirect($this->generateUrl('MySpace_formulaire_recherche_ensembles'));
            }

        //retourner le formulaire d'ajout si c'est invalide
        else {
                return $this->render('MySpaceGestionPatrimoinesBundle:Ensembles:documentsensemble.html.twig', array('formUpload' => $formUpload->createView(), 'message' => $message ));
             }

    }

最后,我在另一个表单中调用表单,有很多方法和方法可以这样做,比如检查西佛尼烹饪书这里,就像Abdallah Arffak建议的那样。

非常感谢,如果我的英语不好,很抱歉。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-29 14:11:22

你应该用这个

代码语言:javascript
复制
{{ form_label(formEnsemble.file, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
        <div>
         {{ form_widget(formEnsemble.file) }}
        </div>
      </div>

而不是这个

代码语言:javascript
复制
{{ form_label(formEnsemble.documentsensemble, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
        <div>
         {{ form_widget(formEnsemble.documentsensemble) }}
        </div>
      </div>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27688888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档