使用symfony2上传文件

时间:2015-07-25 22:54:36

标签: php symfony file-upload

我是symfony的新手,我使用Symfony 2.7和wamp服务器。我尝试按照Symfony doc / cookbook实现上传方法。 这是我的实体:

<?php

namespace NoticiaBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraint as Assert;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * Imagem
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="NoticiaBundle\Repository\ImagemRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Imagem
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    public $path;

    /**
     * @ORM\OneToMany(targetEntity="Noticia", mappedBy="imagem")
     */
    private $noticias = array();

    public function __construct()
    {
        $this->noticias = new ArrayCollection();

    }

    public $file;

    public function getUploadRootDir()
    {
        return __dir__.'/../../../../web/uploads';
    }

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

    /**
     * @ORM\Prepersist()
     * @ORM\Preupdate()
     */
    public function preUpload()
    {
        $this->tempFile = $this->getAbsolutePath();
        $this->oldFile = $this->getPath();

        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){
            $this->file->move($this->getUploadRootDir(),$this->path);
            unset($this->file);

            if($this->oldFile !==null) unlink($this->tempFile);
        }
    }

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

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

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

    public function getPath()
    {
        return $this->path;
    }

    public function getName()
    {
        return $this->name;
    }

 }

我的实体与外键图像

<?php

namespace NoticiaBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Noticia
 *
 * @ORM\Table(name="NOTICIA")
 * @ORM\Entity(repositoryClass="NoticiaBundle\Repository\NoticiaRepository")
 * @ORM\HasLifecycleCallbacks
 */
class Noticia
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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

    /**
     * @ORM\ManyToOne(targetEntity="Imagem", cascade={"persist", "remove"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $imagem;


    /**
     * @ORM\ManyToOne(targetEntity="Categoria", inversedBy="noticias")
     * @ORM\JoinColumn(name="categoria_id", referencedColumnName="id")
     */
    private $categoria;


    /**
     * @ORM\OneToMany(targetEntity="Comentario", mappedBy="noticia")
     */
    private $comentarios = array();

    public function __construct()
    {
        $this->comentarios = new ArrayCollection();

        $this->setDtCadastro(new \DateTime());
        $this->setDtAtualizacao(new \DateTime());
    }

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dt_cadastro", type="datetime")
     */
    private $dtCadastro;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="dt_atualizacao", type="datetime")
     */
    private $dtAtualizacao;

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

    /**
     * Set titulo
     *
     * @param string $titulo
     * @return Noticia
     */
    public function setTitulo($titulo)
    {
        $this->titulo = $titulo;

        return $this;
    }

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

    /**
     * Set noticia
     *
     * @param string $noticia
     * @return Noticia
     */
    public function setNoticia($noticia)
    {
        $this->noticia = $noticia;

        return $this;
    }

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

    /**
     * Set imagem
     *
     * @param string $imagem
     * @return Noticia
     */
    public function setImagem($imagem)
    {
        $this->imagem = $imagem;

        return $this;
    }

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

    /**
     * Set categoria
     *
     * @param string $categoria
     * @return Noticia
     */
    public function setCategoria($categoria)
    {
        $this->categoria = $categoria;

        return $this;
    }

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

    public function addComentario(Comentario $comentario)
    {
        $this->comentarios[] = $comentario;

        return $this;
    }

    public function getComentarios()
    {
        return $this->comentarios;
    }

    /**
     * Set dtCadastro
     *
     * @param \DateTime $dtCadastro
     * @return Noticia
     */
    public function setDtCadastro($dtCadastro)
    {
        $this->dtCadastro = $dtCadastro;

        return $this;
    }

    /**
     * Get dtCadastro
     *
     * @return \DateTime 
     */
    public function getDtCadastro()
    {
        return $this->dtCadastro;
    }

    /**
     * Set dtAtualizacao
     *
     * @param \DateTime $dtAtualizacao
     * @return Noticia
     */
    public function setDtAtualizacao($dtAtualizacao)
    {
        $this->dtAtualizacao = $dtAtualizacao;

        return $this;
    }

    /**
     * Get dtAtualizacao
     *
     * @return \DateTime 
     */
    public function getdtAtualizacao()
    {
        return $this->dtAtualizacao;
    }

    /**
     * @ORM\PreUpdate
     */
    public function setDtAtualizacaoValue()
    {
        $this->setDtAtualizacao(new \DateTime());
    }

    /**
     * Remove comentarios
     *
     * @param \NoticiaBundle\Entity\Comentario $comentarios
     */
    public function removeComentario(\NoticiaBundle\Entity\Comentario $comentarios)
    {
        $this->comentarios->removeElement($comentarios);
    }

}

我的imagem表单类型

<?php

namespace NoticiaBundle\Form;

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

class ImagemType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('file','file',array('required' => false));
    }

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

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

Noticia FormType

<?php

namespace NoticiaBundle\Form;

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

class NoticiaType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('titulo',null, array('attr' => array('class' => 'form-control'),
                'label_attr' => array('class' => 'control-label col-lg-2')
            ))
            ->add('imagem',  new ImagemType(),
                array('label_attr' => array('class' => 'control-label col-lg-2')
            ))
            ->add('noticia','textarea', array('attr' => array('class' => 'form-control', 'rows' => 15),
                'label_attr' => array('class' => 'control-label col-lg-2')
            ))
            ->add('categoria', 'entity', array('attr' => array('class' => 'form-control'),
                'label_attr' => array('class' => 'control-label col-lg-2'),
                'class' => 'NoticiaBundle:Categoria',
                'property' => 'nome',
                'placeholder' => 'Escolha...',
            ))
            ->add('salvar', 'submit', array('attr' => array('class' => 'btn btn-primary pull-right')));
    }

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

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

控制器功能可以保留Noticias和图像(上传文件)

/**
     * Add new Noticia.
     *
     * @Route("/noticia/novo", name="nova_noticia")
     * @Template()
     */
    public function novoAction(Request $request)
    {
        $form = $this->createForm(new NoticiaType(), new Noticia());

        $form->handleRequest($request);

        if ($form->isValid()) {
            $noticia = $form->getData();


            $noticia->setLogin($_SESSION['colaborador_login']);

            $noticiaRepository = $this->getDoctrine()->getRepository('NoticiaBundle:Noticia');

            try {
                $noticiaRepository->novo($noticia);

                $this->get('session')->getFlashBag()
                    ->add('success', 'Iserido com sucesso!');

                return $this->redirect($this->generateUrl('noticias_index'));
            } catch (\Exception $e) {
                $this->get('session')->getFlashBag()->add(
                    'danger', $e->getMessage()
                );

            }
        }
        return $this->render("NoticiaBundle:Noticia:formulario.html.twig",
            array('form' => $form->createView()));
    }

我更改了我的实体上传文件,现在他正在保存正确的路径,但该文件已保存到项目目录中

1 个答案:

答案 0 :(得分:0)

没有简单的方法来测试你的代码,只是看一下它,我看到的最明显的问题是你在保存文件之前没有调用函数preUpload

您可能需要preUpload功能的以下注释。

/**
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */