Symfony 3.0错误:文件" IMG_20160305_155302.jpg"因未知错误而未上传

时间:2016-03-05 21:36:11

标签: php symfony

基于:http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html

我制作了一个图像模型:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Filesystem\Filesystem;

/**
* @ORM\Entity
* @ORM\Table(name="images")
* @ORM\Entity(repositoryClass="AppBundle\Entity\ImagesRepository")
* @ORM\HasLifecycleCallbacks
*/
class Images
{
    /**
     * @ORM\Column(type="string", length=60)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="AppBundle\Doctrine\AutoIdGenerate")
     */
    private $id;

    /**
    * Filename of the Image
    * @ORM\Column(type="string", length=100)
    */
    private $name;

    /**
    * Filename of the Thumbnail
    * @ORM\Column(type="string", length=100)
    */
    private $name_small;

    /**
    * ImageGroup og the Image
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\ImageGroups", inversedBy="images")
    */
    private $group;


    /**
     * @Assert\File(maxSize="20000000")
     */
    private $file;

    private $upload_dir='images';
    private $temp;

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

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

        // check if we have an old image path
        if (isset($this->name))
        {
            // store the old name to delete after the update
            $this->temp = $this->name;
            $this->name = null;
        }
        else
        {
            $this->name = sha1(uniqid(mt_rand(), true)).'.'.$file->guessExtension();
        }

        $this->name_small="small_".$this->name;
        $this->upload_dir=$upload_dir;

        return $this;
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {
        if (null !== $this->getFile())
        {
            // do whatever you want to generate a unique name
            $filename = sha1(uniqid(mt_rand(), true));
            $this->name = $filename.'.'.$this->getFile()->guessExtension();
            $this->name_small='small_'.$this->name;
        }
    }

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

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {
        if (null === $this->getFile())
        {
            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

        //-- Make the Thumbnail Here --

        $dir=$this->getUploadRootDir();
        echo $dir;
        $fs = new Filesystem();

        if(!$fs->exists($dir))
        {
          echo "\nCreating\n";
          $fs->mkdir($dir,0777,true);
        }

        $this->getFile()->move($dir, $this->name);

        $file=$dir.'/'.$this->name;

        // check if we have an old image
        if (isset($this->temp))
        {
            // delete the old image
            unlink($this->getUploadRootDir().'/'.$this->temp);
            // clear the temp image path
            $this->temp = null;
        }
        $this->file = null;
    }

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


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


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

    /**
     * Get nameSmall
     *
     * @return string
     */
    public function getNameSmall()
    {
        return $this->name_small;
    }

    /**
     * Set group
     *
     * @param \AppBundle\Entity\ImageGroups $group
     *
     * @return Images
     */
    public function setGroup(\AppBundle\Entity\ImageGroups $group = null)
    {
        $this->group = $group;

        return $this;
    }

    /**
     * Get group
     *
     * @return \AppBundle\Entity\ImageGroups
     */
    public function getGroup()
    {
        return $this->group;
    }

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

        return $this;
    }

    /**
     * Set nameSmall
     *
     * @param string $nameSmall
     *
     * @return Images
     */
    public function setNameSmall($nameSmall)
    {
        $this->name_small = $nameSmall;

        return $this;
    }
}

我还制作了自定义存储库以进行上传:

<?php
namespace AppBundle\Entity;

use Doctrine\ORM\EntityRepository;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use AppBundle\Entity\Images;

class ImagesRepository extends EntityRepository
{

  public function add($file,$group_id,$user_id)
  {

    if(empty($group_id)) return -1;
    if(empty($user_id)) return -2;

    /*Do stuff for uploads*/
    /*End of Do stuff for uploads*/



    $em = $this->getEntityManager();

    $imagesGroups = $em->getRepository('AppBundle:ImageGroups')
                       ->getUserImageGroups($user_id,null,$group_id);

    if(empty($imagesGroups) ||(is_int($imagesGroups) && $imagesGroups<0)) return -3; //Null and negative values are false

    if(empty($file)) return -4;

    $image=new Images();
    $image->setFile($file,'images')->setGroup($imagesGroups);

    try
    {
      $em->persist($image);
      $em->flush();

      return ['id'=>$image->getId(),'image'=>$image->getName(),'thumb'=>$image->getNameSmall()];
    }
    catch (\Exception $e)
    {
      echo $e->getMessage();
        return false;
    }
  }

  public function delete($user_id,$image_id)
  {
    if(empty($image_id)) return -1;
    if(empty($user_id)) return -2;

    $em = $this->getEntityManager();

    try
    {
      $q=$em->createQueryBuilder('i')
            ->from('AppBundle:Images','i')
            ->innerJoin('i.group', 'g')
            ->innerJoin('AppBundle:Users','u')
            ->select('i')
            ->where('i.id=:iid')
            ->andWhere('u.id=:uid')
            ->setParameter(':uid', $user_id)
            ->setParameter(':iid', $image_id)
            ->setMaxResults(1)
            ->getQuery();

      $data=$q->getOneOrNullResult();

      if(empty($data)) return -3;

      /*Delete Image Stuff*/
      /*End Of: Delete Image Stuff*/

      $em->remove($data);
      $em->flush();

      return true;

    }
    catch (\Exception $e)
    {
      echo $e->getMessage();
      return false;
    }


  }

}

当我成功执行POST操作(我使用curl测试上面的代码)时出于某种原因我得到以下错误:

The file "IMG_20160305_155302.jpg" was not uploaded due to an unknown error.

通过回显Exception消息。

我原本认为这是我的文件系统上的权限问题因此在文件夹/home/pcmagas/Kwdikas/php/apps/symphotest/src/AppBundle/Entity/../../../../web/images

我设置了以下权限:

drwxrwxrwx 2 www-data www-data  4096 Μάρ   5 23:02 images

但似乎不是问题所在。我想知道还有什么呢。 我可以有解决方案吗?

编辑1: 我检查了php.ini上的upload_max_filesize并且是2M,我上传的文件是56,0 Kbytes。

1 个答案:

答案 0 :(得分:0)

UploadedFile实例在某种程度上没有在控制器中进行核心设置。

为了获取文件输入,我创建了这个类:

<?php
namespace AppBundle\Helpers;

use Symfony\Component\HttpFoundation\File\UploadedFile;

class MyUploadedFile
{
  /**
  *Storing Uploaded Files
  */
  private $files=null;

  function __construct($string)
  {
    if(isset($_FILES[$string]))
    {
      $files=$_FILES[$string];

      if(is_array($files['name']))
      {
        $this->files=array();

        $tmp_files=array();

        /**
        *Sanitizing When Multiple Files
        */
        foreach($files as $key=>$val)
        {
          foreach($val as $key2=>$val2)
          {
            $tmp_files[$key2][$key]=$val2;
          }
        }

        foreach($tmp_files as $val)
        {
          $this->files[]=new UploadedFile($val['tmp_name'],$val['name'],$val['type'],$val['size'],$val['error']);
        }

      }
      elseif(is_string($files['name']))
      {
        $this->files= new UploadedFile($files['tmp_name'],$files['name'],$files['type'],$files['size'],$files['error']);
      }
    }
  }

  /**
  *@return {UploadedFile} Or {Array of UploadedFile} or null
  */
  public function getFiles()
  {
    return $this->files;
  }
}
?>

特别是在这些行中

 $this->files= new UploadedFile($files['tmp_name'],$files['name'],$files['type'],$files['size'],$files['error']);

$this->files[]=new UploadedFile($val['tmp_name'],$val['name'],$val['type'],$val['size'],$val['error']);

因此,当您手动创建上传文件时,大小会出现在错误

之前