上传Symfony2中的文件:Catchable Fatal Error:Argument 1传递给

时间:2014-12-29 12:27:54

标签: php symfony file-upload doctrine-orm controller

我使用 Symfony2和wamp服务器。我尝试在Symfony doc/cookbook之后实施上传方法

我有两个实体DocumentsEnsemble.phpEnsembles.php。 DocumentsEsesembles是我存储上传文件的实体,用于 1 合奏(图片,文档,pdf等...)。 合奏可以包含 0或文档,文档可以属于 0或1单合奏。< / p>

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

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);
        }
    }

我想像你在Ensembles中看到的那样实现上传方法。这是名为DocumentsEnsembles.php的DocumentsEnsemble实体:

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方法的表单中,我可以在我的Ensembles实体中添加一个集合。此表单包含要上传文件的输入文件属于整体。我使用由名为EnsemblesType.php的Doctrine生成的表单,这是以下代码:

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';
    }
}

这是我的addEnsembles.html.twig,其形式为post方法:

<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>

当我提交表单时,我有这个错误:

  

捕获致命错误:参数1传递给   MySpace \ DatabaseBundle \ Entity \ Ensembles :: setDocumentsensemble()必须   是MySpace \ DatabaseBundle \ Entity \ Documentsensemble的一个实例,   给出了Symfony \ Component \ HttpFoundation \ File \ UploadedFile的实例,   呼唤   C:\瓦帕\ WWW \ BitbucketRepository \回购\ SymfonyGirusMySpace \厂商\ symfony的\ symfony的\ SRC \的Symfony \元器件\ PropertyAccess \ PropertyAccessor.php   在第438行并在中定义   C:\ WAMP \ WWW \ BitbucketRepository \回购\ SymfonyGirusMySpace的\ src \ MySpace的\ DatabaseBundle \实体\ Ensembles.php   第411行

为了找到合适的解决方案,有人可以解释一下吗?我是否正确上传文件方法?

这是我的控制器方法,用于添加带有上传文件的Ensemble:

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的代码:

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

现在Documentsensembles.php的代码包含上传方法(回调等等):

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

现在是控制器的代码:

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 ));
             }

    }

最后,我在另一种形式的树枝中调用表单,有很多方法和方法可以执行此操作,请查看the symfony cookbookhere,例如Abdallah Arffak建议我。

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

1 个答案:

答案 0 :(得分:0)

你应该使用这个

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

而不是

{{ form_label(formEnsemble.documentsensemble, "Transférer un fichier appartenant à cet ensemble:", {'label_attr': {'class': 'control-label'}}) }}
        <div>
         {{ form_widget(formEnsemble.documentsensemble) }}
        </div>
      </div>