当我尝试将多个图像上传到数据库时,我遇到了问题。 我已经阅读了symfony文档,我每次都可以上传一张图片。 我也读过
http://symfony.com/doc/current/cookbook/form/form_collections.html
到目前为止,我完全理解上传ONE IMAGE的过程,但是当您需要上传多张图片时会发生什么? 这是我的情况,我有一个Store实体和一个StorePhoto实体,一个商店包含与StorePhoto的OneToMany关系(变量commerce_photos),(我正在为商店开发某种图像库。) 我的想法是一次上传多张图片,我的意思是选择多个文件并上传它们。 这就是我所做的
我的商店实体
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
* @ORM\Table(name="store")
*
*/
class Store{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255)
*/
protected $name;
/**
* @ORM\OneToOne(targetEntity="StorePhoto")
*/
protected $photo;
/**
* @ORM\OneToMany(targetEntity="StorePhoto", mappedBy="store_photo")
*/
protected $commerce_photos;
public function __construct(){
$this->commerce_photos = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Store
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Add commerce_photos
*
* @param \AppBundle\Entity\StorePhoto $commercePhotos
* @return Store
*/
public function addCommercePhotos(\AppBundle\Entity\StorePhoto $commercePhotos)
{
$this->commerce_photos[] = $commercePhotos;
return $this;
}
/**
* Remove commerce_photos
*
* @param \AppBundle\Entity\StorePhoto $commercePhotos
*/
public function removeCommercePhotos(\AppBundle\Entity\StorePhoto $commercePhotos)
{
$this->commerce_photos->removeElement($commercePhotos);
}
/**
* Get commerce_photos
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCommercePhotos()
{
return $this->commerce_photos;
}
}
我的StorePhoto实体
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* @ORM\Entity
* @ORM\Table(name="store_photo")
*/
class StorePhoto{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @ORM\Column(type="string", length=255)
*/
protected $imageName;
/**
* @ORM\Column(type="string", length=255,nullable=false)
*/
protected $path;
/**
* @ORM\ManyToOne(targetEntity="Store", inversedBy="commerce_photos")
*/
protected $store_photo;
/**
* @Assert\Image
(mimeTypes = {"image/jpg", "image/jpeg", "image/gif", "image/png"},
mimeTypesMessage = "Solo acepta imagenes en formato JPG, GIF ou PNG.",
maxSize="5000k")
*/
private $imageFile;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Get file.
*
* @return UploadedFile
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* Sets file.
*
* @param UploadedFile $imageFile
*/
public function setImageFile(UploadedFile $file = null)
{
$this->imageFile = $file;
}
/**
* Set imageName
*
* @param string $imageName
* @return StorePhoto
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* Get imageName
*
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* Set store_photo
*
* @param \AppBundle\Entity\Store $storePhoto
* @return StorePhoto
*/
public function setStorePhoto(\AppBundle\Entity\Store $storePhoto = null)
{
$this->store_photo = $storePhoto;
return $this;
}
/**
* Get store_photo
*
* @return \AppBundle\Entity\Store
*/
public function getStorePhoto()
{
return $this->store_photo;
}
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 where uploaded documents should be saved
return __DIR__.'/../../../../web/images'.$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';
}
public function upload()
{
//the file property can be empty if the field is not required
if(null === $this->getImageFile())
{
return;
}
//use the original file name here but you should
//sanitaze it at least to avoid any security issues
//move takes the target directory and then the target filename to move to.
$this->getImageFile()->move(
$this->getUploadRootDir(), $this->getImageFile()->getClientOriginalName()
);
//set the path property to the filename where you've saved the file
$this->path = $this->getImageFile()->getClientOriginalName();
//clean up the file property as you won't need it anymore...
$this->imageFile = null;
}
}
我的控制器
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use AppBundle\Forms\Type\FileUploadType;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\StorePhoto;
use AppBundle\Entity\Store;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Forms\Type\MultipleFileUploadType;
class DefaultController extends Controller
{
public function multipleFileUploadAction(Request $request)
{
$store = new Store();
$store->setName('Test01');
$store->addCommercePhotos(new StorePhoto());
$form = $this->createForm(new MultipleFileUploadType(),$store);
$form->handleRequest($request);
if($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$em->persist($store);
$em->flush();
return new Response('200 OK...');
}
return $this->render('Forms/FileUpload.html.twig',array('form'=>$form->createView()));
}
}
我的表单现在,FileUploadType和MultipleFileUploadType
<?php
namespace AppBundle\Forms\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('imageName', 'text');
$builder->add('imageFile', 'file',
array('multiple'=>'multiple'));
// $builder->add('Save', 'submit');
}
public function getName()
{
return "storePhoto";
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\StorePhoto',
));
}
}
?>
<?php
namespace AppBundle\Forms\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use AppBundle\Forms\Type\FileUploadType;
class MultipleFileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name','text');
$builder->add('commerce_photos', 'collection',array(
'type' => new FileUploadType()));
$builder->add('Save', 'submit');
}
public function getName()
{
return "MultipleFileUpload";
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Store',
));
}
}
?>
这是所有代码,我不知道我是否在这里遗漏了一些东西。 我需要做的是显示对话框,选择几个图像,然后保存它们。 在这种情况下,在控制器中我写了这一行
$store = new Store();
$store->setName('Test01');
$store->addCommercePhotos(new StorePhoto());
在这种情况下,当我渲染表单时,它会显示一个对话框,只允许我选择一个文件。 如果我删除第三行,addCommerce ...它只显示标签为commercePhotos。
提前致谢!
答案 0 :(得分:0)
在你没有为field commerce_photos设置值之前,Symfony会将其识别为空。对于空字段,它不会呈现输入元素。所以你需要自己设置一些虚拟值或渲染字段:
{{ form_label(form.imageFile) }}
<input type="file" name="{{ form.imageFile.vars.fullName }}[]" class="file-upload" />
方括号对于使Symfony处理多个值非常重要。要使表单一次接受多个文件,您可能需要一些这样的jquery:
$('.file-upload').on('change', function (event) {
$(event.currentTarget).after('<input type="file" name="{{ form.imageFile.vars.fullName }}[]" class="file-upload" />');
});