使用Dropzone多上传Symfony 2.3

我尝试了一个新的JQuery库实现: dropzone.js

该库提供了一个带拖放解决方案的良好的多上传界面。

似乎Symfony的多上传系统并不容易。

我有这个错误:

Error: Cannot use object of type Symfony\Component\HttpFoundation\File\UploadedFile as array in /vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php line 87 

我的实体文件:

 /** * @ORM\Entity * @ORM\Table(name="media__file") * @ORM\HasLifecycleCallbacks */ class File { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ public $id; /** * @ORM\Column(type="string", length=255) * @Assert\NotBlank */ public $name; /** * @ORM\Column(type="string", length=255, nullable=true) */ public $path; /** * @Assert\File(maxSize="6000000") */ public $file; 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() { return __DIR__.'/../../../../../web/'.$this->getUploadDir(); } protected function getUploadDir() { return 'uploads/files'; } /** * @ORM\PrePersist() * @ORM\PreUpdate() */ public function preUpload() { 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) { return; } $this->file->move($this->getUploadRootDir(), $this->path); unset($this->file); } /** * @ORM\PostRemove() */ public function removeUpload() { if ($file = $this->getAbsolutePath()) { unlink($file); } } 

我的控制器FileController:

 /** * @Route("/admin/media/upload") * @Template() */ public function uploadsAction (){ $file = new File(); $form = $this->createForm(new \Tperroin\Bundle\MediaBundle\Form\FileUploadType(), $file); if ($this->getRequest()->isMethod('POST')) { $form->bind($this->getRequest()); if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($file); $em->flush(); return $this->redirect($this->generateUrl('tperroin_home_default_index')); } } return array('form' => $form->createView()); } 

最后我的树枝模板:

 

编辑:

FormType:

 class FileUploadType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('file', 'file'); } public function getName() { return 'file'; } } 

我的代码出了什么问题? 我知道这是UploadedFile和数组的问题,但我不知道如何解决这个问题。

感谢你所做的一切 !

编辑:

也许这个链接可以帮助某人,我无法重现这个:

Symfony2中多文件上载的问题

使用新的uploadAction函数编辑:

 /** * @Route("/upload/process", name="upload_media") */ public function uploadAction() { $request = $this->get('request'); $files = $request->files; $directory = $this->get('kernel')->getRootDir() . '/../web' . $this->getRequest()->getBasePath() . '/files/'; foreach ($files as $uploadedFile) { $name = $uploadedFile->getClientOriginalName(); $file = $uploadedFile->move($directory, $name); $upload = new File($name); $em = $this->get('doctrine')->getManager(); $em->persist($upload); $em->flush(); } return $this->redirect($this->generateUrl('tperroin_media_default_index')); } 

首先,您并没有真正在Twig模板中使用FileUploadType 。 您可以手动创建表单,并将action路径设置为您在Controller中定义的URL。 您传递给模板的表单视图中唯一使用的是form_enctype 。 但是像大多数多文件上传者一样,Dropzone似乎伪造了自己的上传图片的请求。

这意味着您还必须手动处理传入的数据。

 /** * @Route("/admin/media/upload") * @Template() */ public function showUploadAction() { // just show the template return []; } /** * @Route("/admin/media/upload/process", name="upload_media") */ public function uploadAction() { $request = $this->get('request'); $files = $request->files; // configuration values $directory = //... // $file will be an instance of Symfony\Component\HttpFoundation\File\UploadedFile foreach ($files as $uploadedFile) { // name the resulting file $name = //... $file = $uploadedFile->move($directory, $name); // do something with the actual file $this->doSomething($file); } // return data to the frontend return new JsonResponse([]); } 

方法uploadAction从Symfony的请求中获取FileBag ,迭代它,并在生成的文件上执行自定义逻辑。 当然,您必须自己处理File实体的存储。

您的模板应如下所示:

 

感谢这个问题,我注意到Dropzone上传器并在OneupUploaderBundle中集成了对它的支持 。 所以你可以使用这个包简化了上面提到的几个步骤。

Symfony要求每个表单都包含一个csrf-token。 您的表单不包含一个,因此symfony尝试使用您的“文件”-field作为csrf-token并抛出错误。 解决此问题的第一步是在form-element中使用此代码段呈现csrf-token:

 {{ form_widget(form) }} 

然后你必须改变它可以处理多个文件的实体。 这可以通过实现一对多关系(上传(一)到文件(很多))来完成。

在Symfony中,如果您有错误

 Error: Call to a member function move() on a non-object 

尝试改变

 $files = $request->files 

 $files = $request->files->get('file');