如何从PHP表单获取uploadedFile数组

时间:2017-01-13 16:12:39

标签: php arrays file-upload doctrine-orm symfony

我是PHP的新手。我成功地将单个图像上传到表单并将其保存在数据库中。但是当我修改它以上传多个图像时,我收到错误说

  

表单的视图数据应该是Symfony \ Component \ HttpFoundation \ File \ File类的实例,但是是(n)数组。

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



/**
 *  @var array
 */
    private $files= array();


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

    /**
     *Set files
     *
     * @param UploadedFile[] $files
     */
    public function setFiles($files)
    {
        $this->files = $files;

        //return $this;
    }

    /**
     * Get files
     *
     * @return UploadedFile[]
     */
    public function getFiles()
    {
        return $this->files;
    }

    /**
     * @param satelliteImage[] $images
     *
     * @return satelliteImage[]
     *
     */
    public function upload($images){
        foreach ($this->getFiles() as $key => $file) {
            $images[$key]->setImage(file_get_contents($file));
        }
        return $images;
    }
}

这是SatelliteImage实体(单张图片)

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

        /**
         * @var float
         *
         * @ORM\Column(name="latitude", type="float")
         */
        private $latitude;

        /**
         * @var float
         *
         * @ORM\Column(name="longitude", type="float")
         */
        private $longitude;

        /**
         * @var string
         *
         * @ORM\Column(name="image", type="blob", nullable=true))
         */
        private $image;

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


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

        /**
         * Set latitude
         *
         * @param float $latitude
         *
         * @return satelliteImage
         */
        public function setLatitude($latitude)
        {
            $this->latitude = $latitude;

            return $this;
        }

        /**
         * Get latitude
         *
         * @return float
         */
        public function getLatitude()
        {
            return $this->latitude;
        }

        /**
         * Set longitude
         *
         * @param float $longitude
         *
         * @return satelliteImage
         */
        public function setLongitude($longitude)
        {
            $this->longitude = $longitude;

            return $this;
        }

        /**
         * Get longitude
         *
         * @return float
         */
        public function getLongitude()
        {
            return $this->longitude;
        }

        /**
         * Set image
         *
         * @param string $image
         *
         * @return satelliteImage
         */
        public function setImage($image)
        {
            $this->image = $image;

            return $this;
        }

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

        /**
         * 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;
        }

        protected function getUploadRootDir()
        {
            // the absolute directory path 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';
        }

        /**
         * @Assert\File(maxSize="6000000")
         */
        private $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;
        }


        public function upload()
        {
        // the file property can be empty if the field is not required
        if (null === $this->getFile()) {
            return;
        }

        $imgFile=$this->getFile();
        $this->setImage(file_get_contents($imgFile)); 

        // clean up the file property as you won't need it anymore
        $this->file = null;
        }
    }

在我的控制器中,如何创建图像数组并将其传递给上述函数?

/**
     * @Route("/uploads", name="upload_images")
     *
     */
    public function uploadImages(Request $request)
    {
        $images=new Images();

        $form = $this->createForm(ImageFile::class, $images);
        $form->handleRequest($request);

        $em=$this->getDoctrine()->getManager();
        $images->upload(????);
    }

ImageFile类:

class ImageFile extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('files', FileType::class, array(
                'attr' => array(
                    'accept' => 'image/*',
                    'multiple' => 'multiple'
                )
            ))
            ->add('save',SubmitType::class,array('label'=>'Insert Image','attr'=>array('class'=>'btn btn-primary','style'=>'margin-bottom:15px')))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => SatelliteImages::class
        ));
    }
}

2 个答案:

答案 0 :(得分:1)

这里的代码是一个问题:

/**
 * @Assert\File(maxSize="60000000")
 */
private $files= array();

你需要解决这个问题。你声称它是一个文件,但是你指定它是一个数组!

编辑#2

您的upload功能也存在问题。您将返回传入的相同参数($ images)。所以你需要改变它:

/**
 * @param satelliteImage[] $images
 *
 * @return satelliteImage[]
 *
 */
public function upload($images){
    foreach ($this->getFiles() as $key => $file) {
        $img[$key]->setImage(file_get_contents($file));
    }
    return $img;
}

编辑#3

buildForm函数似乎没问题。在你的Controller中,我认为你需要创建类并加载这样的表单:

$images = new SatelliteImages();

$form = $this->createFormBuilder($images);
$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
    $images = $form->getData();

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

    return $this->redirectToRoute('some_path');
}
你可以尝试一下吗?不确定是否存在问题。

答案 1 :(得分:0)

<强>解

我设法通过在imageFile类的buildForm()函数中将'FileType'更改为'CollectionType'来解决上一个问题

    {
        "date": "2016-06-01",
        "duration": "00:13:25",
        "subTitle": "A world first is one click away!",
        "title": "Alice in wonderland\u2026"
    }

我也像这样改变了'文件'

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('files', CollectionType::class, array(
                'attr' => array(
                    'accept' => 'image/*',
                    'multiple' => 'multiple'
                )
            ))
            ->add('save',SubmitType::class,array('label'=>'Insert Image','attr'=>array('class'=>'btn btn-primary','style'=>'margin-bottom:15px')))
        ;
    }

但是,当我这样做时,“浏览图像”按钮会从视图中消失。有什么建议可以解决这个问题吗?

我也尝试删除construct()函数。当我这样做时,它在控制器中给出了一个错误,说“为foreach提供了无效的参数”