使用symfony上传图像。图像未保存在正确的路径中

时间:2015-08-18 11:14:21

标签: image symfony upload

我是Symfony的新人。我一直在尝试创建一个可重用的表单并使用它上传图像。问题是图像没有保存在我给出的路径中。我不知道我做错了什么。我真的很感激任何建议。

实体

<?php

namespace test\TestBundle\Entity\media;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\validator\Constraints as Assert;

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

/**
 * @ORM\Column(name="name",type="string",length=255)
 * @Assert\NotBlank
 */
public $name;

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

public $file;

/**
 * @ORM\PostLoad()
 */
public function postLoad()
{
    $this->updateAt = new \DateTime();
}



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

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

public function getAssetPath()
{
    return 'uploads/'.$this->path;
}

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

    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()
{
    var_dump($this->name);
    return $this->name;
}
}

控制器     

namespace test\TestBundle\Controller\media;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use test\TestBundle\Entity\media\Media;
use test\TestBundle\Form\media\MediaType;

/**
 * media\Media controller.
 *
 * @Route("/img")
 */
class MediaController extends Controller
{

/**
 * Lists all media\Media entities.
 *
 * @Route("/", name="img")
 * @Method("GET")
 * @Template()
 */
public function indexAction()
{
    $em = $this->getDoctrine()->getManager();

    $entities = $em->getRepository('testTestBundle:media\Media')->findAll();

    return array(
        'entities' => $entities,
    );
}
/**
 * Creates a new media\Media entity.
 *
 * @Route("/", name="img_create")
 * @Method("POST")
 * @Template("testTestBundle:media\Media:new.html.twig")
 */
public function createAction(Request $request)
{
    $entity = new Media();
    $form = $this->createCreateForm($entity);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $em->persist($entity);
        $em->flush();
        return $this->redirect($this->generateUrl('img_show', array('id' => $entity->getId())));
    }

    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );
}

/**
 * Creates a form to create a media\Media entity.
 *
 * @param Media $entity The entity
 *
 * @return \Symfony\Component\Form\Form The form
 */
private function createCreateForm(Media $entity)
{
    $form = $this->createForm(new MediaType(), $entity, array(
        'action' => $this->generateUrl('img_create'),
        'method' => 'POST',
    ));

    $form->add('submit', 'submit', array('label' => 'Create'));

    return $form;
}

/**
 * Displays a form to create a new media\Media entity.
 *
 * @Route("/new", name="img_new")
 * @Method("GET")
 * @Template()
 */
public function newAction()
{
    $entity = new Media();
    $form   = $this->createCreateForm($entity);

    return array(
        'entity' => $entity,
        'form'   => $form->createView(),
    );
}

/**
 * Finds and displays a media\Media entity.
 *
 * @Route("/{id}", name="img_show")
 * @Method("GET")
 * @Template()
 */
public function showAction($id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('testTestBundle:media\Media')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find media\Media entity.');
    }

    $deleteForm = $this->createDeleteForm($id);

    return array(
        'entity'      => $entity,
        'delete_form' => $deleteForm->createView(),
    );
}

/**
 * Displays a form to edit an existing media\Media entity.
 *
 * @Route("/{id}/edit", name="img_edit")
 * @Method("GET")
 * @Template()
 */
public function editAction($id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('testTestBundle:media\Media')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find media\Media entity.');
    }

    $editForm = $this->createEditForm($entity);
    $deleteForm = $this->createDeleteForm($id);

    return array(
        'entity'      => $entity,
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    );
}

/**
* Creates a form to edit a media\Media entity.
*
* @param Media $entity The entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Media $entity)
{
    $form = $this->createForm(new MediaType(), $entity, array(
        'action' => $this->generateUrl('img_update', array('id' => $entity->getId())),
        'method' => 'PUT',
    ));

    $form->add('submit', 'submit', array('label' => 'Update'));

    return $form;
}
/**
 * Edits an existing media\Media entity.
 *
 * @Route("/{id}", name="img_update")
 * @Method("PUT")
 * @Template("testTestBundle:media\Media:edit.html.twig")
 */
public function updateAction(Request $request, $id)
{
    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('testTestBundle:media\Media')->find($id);

    if (!$entity) {
        throw $this->createNotFoundException('Unable to find media\Media entity.');
    }

    $deleteForm = $this->createDeleteForm($id);
    $editForm = $this->createEditForm($entity);
    $editForm->handleRequest($request);

    if ($editForm->isValid()) {
        $em->flush();

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

    return array(
        'entity'      => $entity,
        'edit_form'   => $editForm->createView(),
        'delete_form' => $deleteForm->createView(),
    );
}
/**
 * Deletes a media\Media entity.
 *
 * @Route("/{id}", name="img_delete")
 * @Method("DELETE")
 */
public function deleteAction(Request $request, $id)
{
    $form = $this->createDeleteForm($id);
    $form->handleRequest($request);

    if ($form->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $entity = $em->getRepository('testTestBundle:media\Media')->find($id);

        if (!$entity) {
            throw $this->createNotFoundException('Unable to find media\Media entity.');
        }

        $em->remove($entity);
        $em->flush();
    }

    return $this->redirect($this->generateUrl('img'));
}

/**
 * Creates a form to delete a media\Media entity by id.
 *
 * @param mixed $id The entity id
 *
 * @return \Symfony\Component\Form\Form The form
 */
private function createDeleteForm($id)
{
    return $this->createFormBuilder()
        ->setAction($this->generateUrl('img_delete', array('id' => $id)))
        ->setMethod('DELETE')
        ->add('submit', 'submit', array('label' => 'Delete'))
        ->getForm()
    ;
}

}

表     

namespace test\TestBundle\Form\media;

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

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

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

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

}

4 个答案:

答案 0 :(得分:0)

我正在使用getView().setVisibility(View.GONE)表单和文件上传我不建议按照官方文档中的描述进行操作。 请查看https://github.com/dustin10/VichUploaderBundle,配置您的上传,链接实体并享受!

答案 1 :(得分:0)

我认为文档是基本文件上传的一个很好的例子。

尝试更新您的实体:

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
 private $id;

/**
 * @ORM\Column(name="name",type="string",length=255)
 * @Assert\NotBlank
 */
 public $name;

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

/**
 * @Assert\File(maxSize="6000000")
 */
 public $file;

     /**
 * Sets file.
 *
 * @param UploadedFile $file
*/
public function setFile(UploadedFile $file = null)
{
    $this->file = $file;
}

/**
* Get file.
*
* @return UploadedFile
*/
public function getFile()
{
    return $this->file;
}

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

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

    return $this;
}

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

/**
 * Set path
 *
 * @param string $path
 * @return File
*/
public function setPath($path)
{
    $this->path = $path;

    return $this;
}

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

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

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

public function getUploadRootDir()
{
    return __DIR__.'/../../../../web/'.$this->getUploadDir();
}

public function getUploadDir()
{
    return 'uploads/documents/';
}

public function upload()
{
    if (null === $this->getFile()){

         return;
    }

    $this->getFile()->move(
        $this->getUploadRootDir(),
        $this->getFile()->getClientOriginalName()
    );

    $this->path = $this->getFile()->getClientOriginalName();
    $this->file = null;
}

在您的控制器中,GET和POST的简单上传操作:

public function UploadAction()
{
    $document = new Media();
    $form = $this->createFormBuilder($document)
       ->add('file')
       ->getForm();

    if ($this->getRequest()->isMethod('POST')) {
        $form->handleRequest($this->getRequest());
        if ($form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $account = $em->getRepository('AccountingAccountBundle:Account')->findOneBy(array('id' => $accountId));

            $document->setAccount($account);
            $document->upload();

            $em->persist($document);
            $em->flush();
        }
    }

    return array('form' => $form->createView());
}

如果此示例无法在您的服务器上运行,则可能是您的文件系统权限存在问题。

答案 2 :(得分:0)

问题出在路径目录中,只需再一个目录返回 dir 。&#39; /../../../../../ web / uploads&# 39 ;;像这样:)

答案 3 :(得分:0)

最简单的想法:

在树枝中创建普通表单,并尝试将/ rebuilt用于下面的自己需要的特性。

我在连接到实体的一些简单上传中使用它,它不是一个很棒的代码(没有文件验证等),但它对你来说是一个好的开始。

如果trait在实体目录中,则配置

$ location变量

以下用户特征上传(

<?php
 namespace AdminBundle\Entity;

 use Symfony\Component\HttpFoundation\File\UploadedFile;
 use Symfony\Component\Filesystem\Filesystem;
 use Symfony\Component\Finder\Finder;

 trait LinkFileTrait
{
     private $location='/../../../web/media/link' ;
     private $path=__DIR__;

public function checkDir(){
    $id=$this->getId();

    $fs=new Filesystem();
    if(!$fs->exists($this->path.$this->location))
        $fs->mkdir($this->path.$this->location);
    $this->setImagePath($this->path.$this->location.'/'.$id.'');
    if(!$fs->exists($this->getImagePath()))
        $fs->mkdir($this->getImagePath());
}

public function getImages(){
    $this->checkDir();
    $finder = new Finder();
    return $finder->files() ->in($this->getImagePath());
}

public function getRandomImage(){
    $images=$this->getImages();
    $images=iterator_to_array($images);
    if(count($images)<1)
        return null;
    shuffle($images);
    return $images[0];
}

public function UploadFile(UploadedFile $file){
    $file->move($this->getImagePath().'/',$file->getClientOriginalName());

}

public function removeImage($file){
    $this->checkDir();
    $fs=new Filesystem();
    if($fs->exists($this->getImagePath().'/'.$file))
        $fs->remove($this->getImagePath().'/'.$file);
}

public function imageExists($image){
    $this->checkDir();
    $fs=new Filesystem();

    return $fs->exists($this->getImagePath().'/'.$image);
}


public function getRelativePath($path){
    $path=strtr($path,"\\","/");
    $x=explode('../web/',$path);
    return $x[1];
}


public function getImageName($path){
    $path=strtr($path,"\\","/");
    $x=explode('/',$path);
    return $x[count($x)-1];
}

public function getFileName($path){
    $x=explode('/',$path);
    return $x[count($x)-1];
}


}

并在您的控制器中

  public function imagesAction(Link $link,Request $request)
{
    $link->checkDir();
    $images=$link->getImages();

    if($request->getMethod()=='POST'){

        $file=$request->files->all()['plik'];
        $link->UploadFile($file);
    }
    return array('link'=>$link,'images'=>$images);
}