php Symfony 2 | 修改具有文件(图片)字段的对象时形成异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14423265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 07:14:19  来源:igfitidea点击:

Symfony 2 | Form exception when modifying an object that has a file(picture) field

phpfile-uploadsymfonysymfony-2.1

提问by Reveclair

I'm using Symfony2. I have an entity Postthat has a title and a picture field.

我正在使用 Symfony2。我有一个实体Post,它有一个标题和一个图片字段。

My problem : Everything is fine when I create a post, I have my picture etc. But when I want to modify it, I have a problem with the "picture" field which is an uploaded file, Symfony wants a file type and it has a string (the path of the uploaded file) :

我的问题:当我创建一个帖子时一切都很好,我有我的图片等等。但是当我想修改它时,我有一个上传文件的“图片”字段的问题,Symfony 想要一个文件类型,它有一个字符串(上传文件的路径):

The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File. 

I'm really stuck with this problem and really don't know how to solve it, any help would be greatly appreciated! Thanks a lot!

我真的被这个问题困住了,真的不知道如何解决它,任何帮助将不胜感激!非常感谢!

Here is my PostType.php(which is used in newAction() and modifiyAction()) and which may cause the problem (Form/PostType.php) :

这是我的PostType.php(在 newAction() 和 modifiyAction() 中使用)并且可能导致问题(Form/PostType.php):

<?php
namespace MyBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;

use MyBundle\Entity\Post;

class PostType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
        ->add('title')
        ->add('picture', 'file');//there is a problem here when I call the modifyAction() that calls the PostType file.
    }

    public function getDefaultOptions(array $options)
    {
        return array(
            'data_class' => 'MyBundle\Entity\Post',
        );
    }

    public static function processImage(UploadedFile $uploaded_file, Post $post)
    {
        $path = 'pictures/blog/';
        //getClientOriginalName() => Returns the original file name.
        $uploaded_file_info = pathinfo($uploaded_file->getClientOriginalName());
        $file_name =
            "post_" .
            $post->getTitle() .
            "." .
            $uploaded_file_info['extension']
            ;

        $uploaded_file->move($path, $file_name);

        return $file_name;
    }

    public function getName()
    {
        return 'form_post';
    }
}

Here is my Post entity(Entity/Post.php) :

这是我的Post 实体Entity/Post.php):

<?php

namespace MyBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Symfony\Component\Validator\Constraints as Assert;

/**
 * MyBundle\Entity\Post
 *
 * @ORM\Table()
 * @ORM\Entity
 */
class Post
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     * @Assert\Image(
     *      mimeTypesMessage = "Not valid.",
     *      maxSize = "5M",
     *      maxSizeMessage = "Too big."
     *      )
     */
    private $picture;

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

   //getters and setters
   }

Here is my newAction()(Controller/PostController.php) Every works fine with this function:

这是我的newAction()( Controller/PostController.php)每个功能都可以正常工作

public function newAction()
{
    $em = $this->getDoctrine()->getEntityManager();
    $post = new Post();
    $form = $this->createForm(new PostType, $post);
    $post->setPicture("");
    $form->setData($post);
    if ($this->getRequest()->getMethod() == 'POST') 
    {
        $form->bindRequest($this->getRequest(), $post);
        if ($form->isValid()) 
        {
            $uploaded_file = $form['picture']->getData();
            if ($uploaded_file) 
            {
                $picture = PostType::processImage($uploaded_file, $post);
                $post->setPicture('pictures/blog/' . $picture);
            }
            $em->persist($post);
            $em->flush();
            $this->get('session')->setFlash('succes', 'Post added.');

            return $this->redirect($this->generateUrl('MyBundle_post_show', array('id' => $post->getId())));
        }
    }

    return $this->render('MyBundle:Post:new.html.twig', array('form' => $form->createView()));
}

Here is my modifyAction()(Controller/PostController.php) :There is a problem with this function

这是我的modifyAction()( Controller/PostController.php) :这个函数有问题

public function modifyAction($id)
{
    $em = $this->getDoctrine()->getEntityManager();
    $post = $em->getRepository('MyBundle:Post')->find($id);
    $form = $this->createForm(new PostType, $post);//THIS LINE CAUSES THE EXCEPTION
    if ($this->getRequest()->getMethod() == 'POST') 
    {
        $form->bindRequest($this->getRequest(), $post);
        if ($form->isValid()) 
        {
            $uploaded_file = $form['picture']->getData();
            if ($uploaded_file) 
            {
                $picture = PostType::processImage($uploaded_file, $post);
                $post->setPicture('pictures/blog/' . $picture);
            }
            $em->persist($post);
            $em->flush();
            $this->get('session')->setFlash('succes', 'Modifications saved.');

            return $this->redirect($this->generateUrl('MyBundle_post_show', array('id' => $post->getId())));
        }
    }
    return $this->render('MyBundle:Post:modify.html.twig', array('form' => $form->createView(), 'post' => $post));
}

回答by Reveclair

I solved the problem setting data_classto nullas follows:

我解决了这个问题设置data_classnull如下:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('title')
    ->add('picture', 'file', array('data_class' => null)
    );
}

回答by Richard Pérez

I would recommend you to read the documentation of file upload with Symfony and Doctrine How to handle File Uploads with Doctrineand a strong recommendation to the part Lifecycle callbacks

我建议您阅读使用 Symfony 和 Doctrine How to handle File Uploads with Doctrine 的文件上传文档以及对Lifecycle callbacks部分的强烈推荐

In a brief you usually in the form use the 'file' variable (see documentation), you can put a different label through the options, then in your 'picture' field, you just store the name of the file, because when you need the src file you can just call getWebpath() method.

简而言之,您通常在表单中使用“文件”变量(请参阅文档),您可以通过选项放置不同的标签,然后在您的“图片”字段中,您只需存储文件的名称,因为当您需要时您可以调用 getWebpath() 方法的 src 文件。

->add('file', 'file', array('label' => 'Post Picture' )
);

to call in your twig template

调用你的树枝模板

<img src="{{ asset(entity.webPath) }}" />

回答by OMG

Please make below change in your PostType.php.

请在您的PostType.php 中进行以下更改。

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('title')
    ->add('picture', 'file', array(
            'data_class' => 'Symfony\Component\HttpFoundation\File\File',
            'property_path' => 'picture'
        )
    );
}