在 Symfony2 中上传文件:可捕获的致命错误:参数 1 传递到


Upload file in Symfony2: Catchable Fatal Error: Argument 1 passed to

我使用Symfony2和wamp服务器。我尝试按照Symfony文档/食谱实现上传方法

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

这是我名为 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';
    }
}

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

<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() must 是 MySpace''DatabaseBundle''Entity''Documentsensemble 的实例, 给定的 Symfony''Component''HttpFoundation''File''UploadedFile 的实例, 被叫入 C:''wamp''www''BitbucketRepository''repos''SymfonyGirusMySpace''vendor''symfony''symfony''src''Symfony''Component''PropertyAccess''PropertyAccessor.php 在第 438 行上并在 C:''wamp''www''BitbucketRepository''repos''SymfonyGirusMySpace''src''MySpace''DatabaseBundle''Entity''Ensembles.php 411路

有人可以解释我以找到正确的解决方案吗?我的上传文件方法是否正确?

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

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

更新解决方案的问题

感谢阿卜杜拉·阿尔夫法克的回答和评论

事实上,我改变了我的 2 个 entites 之间的关系。事实上,上传方法必须在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 ));
             }
    }
最后,我

用另一种形式称呼树枝中的表格,有很多方法和途径可以做到这一点,请查看symfony食谱或这里,例如Abdallah Arffak建议我。

非常感谢,如果我的英语不好,对不起。

你应该使用它

{{ 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>
相关文章: