如何使symfony2 Request对象将UploadedFile对象传递给实体类而不是string

时间:2013-02-19 15:19:53

标签: php symfony yaml

我正在尝试上传带有文件字段的表单。表单加载正常但请求的Symfony \ Component \ HttpFoundation \ Request对象仅将文件表示为字符串而不是UploadedFile对象。

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use some\Bundle\Entity\Images;
use some\Bundle\Form\ImagesType;




/**
 * Images controller.
 *
 */
class ImagesController extends Controller {    
public function createAction(Request $request) {
            $entity = new Images();

            $form = $this->createForm(new ImagesType(), $entity);

            $form->bind($request);
            if ($form->isValid()) {                 

                $em = $this->getDoctrine()->getManager();
                $em->persist($entity);
                $em->flush();

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

            return $this->render('sephaBundle:admin/Images:new.html.twig', array(
                        'entity' => $entity,
                        'form' => $form->createView(),
                    ));
       } 
}

实体类

<?php

namespace some\Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use some\Bundle\Entity\Images;

/**
 * some\Bundle\Entity\Images
 */
class Images {

    /**
     * @var integer $id
     */
    private $id;

    /**
     * @var string $link
     */
    private $link;

    /**
     * @var string $name
     */
    private $name;

    /**
     * @var file $file
     */
    public $file;

     public function getFile() {
        return $this->file;
    }
    public function setFile($file) {
        $this->file = $file;

        return $this;
    }
    /**
     * Get id
     *
     * @return integer 
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set link
     *
     * @param string $link
     * @return Images
     */
    public function setLink($link) {
        $this->link = $link;

        return $this;
    }

    /**
     * Get link
     *
     * @return string 
     */
    public function getLink() {
        return $this->link;
    }

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

    /**
     * Set Name
     *
     * @param string $name
     * @return Images
     */
    public function setName($name) {
        $this->name = $name;

        return $this;
    }

///////////////////////////////////////////////////////////////
    // <editor-fold defaultstate="collapsed" desc="process file storage location">

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

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

    protected function getUploadRootDir() {
        // the absolute directory link where uploaded
        // documents should be saved
        return __DIR__ . '/../../../../web/' . $this->getUploadDir();
    }

    protected function getUploadDir() {
        // get rid of the __DIR__ so it doesn't screw up
        // when displaying uploaded doc/image in the view.
        return 'uploads/documents';
    }

// </editor-fold>
///////////////////////////////////////////////////////////////

    public function preUpload() {
        if (null !== $this->file) {
            // do whatever you want to generate a unique name

            $filename = sha1(uniqid(mt_rand(), true));

            $this->link = $filename . '.' . $this->file->guessExtension();****//error here $this->file is a string instead of UploadedFile object**** 
        }
    }


    public function upload() {
//        if (null === $this->file) {
//            return;
//        }
        // if there is an error when moving the file, an exception will
        // be automatically thrown by move(). This will properly prevent
        // the entity from being persisted to the database on error
        $this->file->move($this->getUploadRootDir(), $this->link);

        unset($this->file);
    }

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

}?>

表单生成类

namespace some\Bundle\Form;

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

class ImagesType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('Name')
            ->add('file','file',array(
                        'label'=>'Image',
                        'data_class' => 'Symfony\Component\HttpFoundation\File\UploadedFile'
                        ));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'sepha\Bundle\Entity\Images'
        ));
    }

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

yaml中的ORM MAP

some\Bundle\Entity\Images:
    type: entity
    table: images
    fields:
        id:
            id: true
            type: integer
            unsigned: false
            nullable: false
            generator:
                strategy: IDENTITY
        name:
            type: string
            length: 20
            fixed: false
            nullable: false
        link:
            type: string
            length: 60
            fixed: false
            nullable: false

    properties:
        file:
          - Image:
              maxSize: 1024k
              mimeTypes: [image/jpeg, image/png, image/gif ]
              mimeTypesMessage: Please upload a valid image of type jpeg,png or gif

    lifecycleCallbacks:
      prePersist: [preUpload]
      preUpdate: [preUpload]
      postPersist: [upload]
      postUpdate: [upload]
      postRemove: [removeUpload]

我该怎么做才能使请求objet以UploadedFile对象而不是字符串来表示文件请求

2 个答案:

答案 0 :(得分:4)

您的模板的表单标记中是否有form_enctype(form)指令?

<form action="{{ path('your_path') }}" {{ form_enctype(form) }} method="POST">

<强>更新

你的班级保护(对于你的实体)应该都受到保护(使用getter和setter)。没有必要将它们私有化。

protected $file;

答案 1 :(得分:2)

您必须从请求中检索文件。

// retrieves an instance of UploadedFile identified by foo
$request->files->get('foo');

http://symfony.com/doc/current/book/http_fundamentals.html