使用 Dropzone 多上传 Symfony 2.3 [英] Multi upload Symfony 2.3 with Dropzone

查看:26
本文介绍了使用 Dropzone 多上传 Symfony 2.3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这个库提供了一个很好的多上传界面,带有拖放解决方案.

Symfony 的多上传系统似乎并不简单.

我有这个错误:

错误:不能在/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Csrf/EventListener/CsrfValidationListener.php 行中使用类型为 SymfonyComponentHttpFoundationFileUploadedFile 的对象作为数组87

我的实体文件:

/*** @ORM实体* @ORMTable(name="media__file")* @ORMHasLifecycleCallbacks*/类文件{/*** @ORMId* @ORMColumn(type="整数")* @ORMGeneratedValue(strategy="AUTO")*/公共 $id;/*** @ORMColumn(type="string", length=255)* @AssertNotBlank*/公共 $name;/*** @ORMColumn(type="string", length=255, nullable=true)*/公共 $path;/*** @AssertFile(maxSize="6000000")*/公共$文件;公共函数 getAbsolutePath(){返回 null === $this->path ?null : $this->getUploadRootDir().'/'.$this->path;}公共函数 getWebPath(){返回 null === $this->path ?null : $this->getUploadDir().'/'.$this->path;}受保护的函数 getUploadRootDir(){返回 __DIR__.'/../../../../../web/'.$this->getUploadDir();}受保护的函数 getUploadDir(){返回上传/文件";}/*** @ORMPrePersist()* @ORMPreUpdate()*/公共函数 preUpload(){if (null !== $this->file) {$this->path = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();}}/*** @ORMPostPersist()* @ORMPostUpdate()*/公共函数上传(){if (null === $this->file) {返回;}$this->file->move($this->getUploadRootDir(), $this->path);未设置($this->文件);}/*** @ORMPostRemove()*/公共函数 removeUpload(){if ($file = $this->getAbsolutePath()) {取消链接($文件);}}

我的控制器 FileController :

/*** @Route("/admin/media/upload")* @模板()*/公共函数uploadsAction(){$file = 新文件();$form = $this->createForm(new TperroinBundleMediaBundleFormFileUploadType(), $file);if ($this->getRequest()->isMethod('POST')) {$form->bind($this->getRequest());如果 ($form->isValid()) {$em = $this->getDoctrine()->getManager();$em->persist($file);$em->flush();返回 $this->redirect($this->generateUrl('tperroin_home_default_index'));}}return array('form' => $form->createView());}

最后是我的树枝模板:

<form action="{{ url('tperroin_media_file_uploads') }}" method="post" {{ form_enctype(form) }} class="dropzone"><div class="fallback"><input name="file" type="file" multiple/>

</表单>

表单类型:

class FileUploadType 扩展 AbstractType{公共函数 buildForm(FormBuilderInterface $builder, array $options){$builder->add('file', 'file');}公共函数 getName(){返回文件";}}

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

谢谢大家!

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

Symfony2 中多文件上传的问题

使用新的uploadAction 函数进行

/*** @Route("/upload/process", name="upload_media")*/公共函数uploadAction(){$request = $this->get('request');$files = $request->files;$directory = $this->get('kernel')->getRootDir() .'/../web' .$this->getRequest()->getBasePath() .'/文件/';foreach ($files as $uploadedFile) {$name = $uploadedFile->getClientOriginalName();$file = $uploadedFile->move($directory, $name);$upload = 新文件($name);$em = $this->get('doctrine')->getManager();$em->persist($upload);$em->flush();}返回 $this->redirect($this->generateUrl('tperroin_media_default_index'));}

解决方案

首先,您并没有真正在 Twig 模板中使用您的 FileUploadType.您手动创建表单并将 action 路径设置为您在控制器中定义的 url.您从传递给模板的表单视图中使用的唯一内容是 form_enctype.但与大多数多文件上传器一样,Dropzone 似乎伪造了自己的上传图片请求.

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

/*** @Route("/admin/media/upload")* @模板()*/公共函数 showUploadAction(){//只显示模板返回 [];}/*** @Route("/admin/media/upload/process", name="upload_media")*/公共函数uploadAction(){$request = $this->get('request');$files = $request->files;//配置值$目录 =//...//$file 将是 SymfonyComponentHttpFoundationFileUploadedFile 的一个实例foreach ($files as $uploadedFile) {//命名生成的文件$name =//...$file = $uploadedFile->move($directory, $name);//对实际文件做一些事情$this->doSomething($file);}//返回数据给前端返回新的 JsonResponse([]);}

uploadAction 方法从 Symfony 的请求中获取 FileBag,对其进行迭代,并对结果文件执行自定义逻辑.当然你必须自己处理File实体的存储.

您的模板应如下所示:

<div class="fallback"><input name="file" type="file" multiple/>

</表单>


感谢这个问题,我注意到了 Dropzone 上传器和集成支持它OneuploaderBundle.所以你可以使用这个包来简化上面提到的几个步骤.

I tried a new implementation of JQuery library : dropzone.js

This library provides a good multi upload interface with drag and drop solution.

It seems that the multi upload system of Symfony isn't easy.

I've this error :

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

My entity File :

/**
* @ORMEntity
* @ORMTable(name="media__file")
* @ORMHasLifecycleCallbacks
*/
class File
{
/**
 * @ORMId
 * @ORMColumn(type="integer")
 * @ORMGeneratedValue(strategy="AUTO")
 */
public $id;

/**
 * @ORMColumn(type="string", length=255)
 * @AssertNotBlank
 */
public $name;

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

/**
 * @AssertFile(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';
}

 /**
 * @ORMPrePersist()
 * @ORMPreUpdate()
 */
public function preUpload()
{
    if (null !== $this->file) {
        $this->path = sha1(uniqid(mt_rand(), true)).'.'.$this->file->guessExtension();
    }
}

/**
 * @ORMPostPersist()
 * @ORMPostUpdate()
 */
public function upload()
{
    if (null === $this->file) {
        return;
    }


    $this->file->move($this->getUploadRootDir(), $this->path);

    unset($this->file);
}

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

My controller FileController :

/**
 * @Route("/admin/media/upload")
 * @Template()
 */
public function uploadsAction (){

    $file = new File();

    $form = $this->createForm(new TperroinBundleMediaBundleFormFileUploadType(), $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());
}

And finally my twig template :

<div class="widget-content">

        <form action="{{ url('tperroin_media_file_uploads') }}" method="post" {{ form_enctype(form) }} class="dropzone">

            <div class="fallback">
                <input name="file" type="file" multiple />
            </div>
        </form>

    </div>

EDIT :

FormType :

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

What is wrong with my code ? I know it's a problem with UploadedFile and array but I don't know how to resolve that.

Thank you for all !

EDIT :

Maybe this link can help someone, I fail to reproduce this :

Problems With Multiple File Upload In Symfony2

EDIT with new uploadAction function :

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

解决方案

First of all, you don't really use your FileUploadType in the Twig template. You create a form manually and set the action path to the url you defined in your Controller. The only thing you use from the form view you pass to the template is the form_enctype. But like most multi file uploaders, Dropzone seems to forge its own request to upload an Image.

This means you also have to handle the incoming data manually.

/**
 * @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 SymfonyComponentHttpFoundationFileUploadedFile
    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([]);
}

The method uploadAction takes the FileBag from Symfony's request, iterates over it, and performs your custom logic on the resulting file. Of course you have to handle the storage of the File entity by yourself.

Your template should look like this:

<form action="{{ path('upload_media') }}" method="post" class="dropzone">
    <div class="fallback">
        <input name="file" type="file" multiple />
    </div>
</form>


Thanks to this question I took notice of the Dropzone uploader and integrated support for it in the OneupUploaderBundle. So you could just use this bundle which simplifies a few steps mentioned above.

这篇关于使用 Dropzone 多上传 Symfony 2.3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
PHP最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆