【问题标题】:Implementation of fully functional media uploading in web application在 Web 应用程序中实现全功能媒体上传
【发布时间】:2013-08-11 04:38:31
【问题描述】:

假设我们有一个处理创建、阅读、更新和删除文章的 Web 应用程序,并且每篇文章都应该有图片库。我必须在文章和画廊之间建立一对一的关系,在画廊和媒体之间建立一对多的关系。

HTML5 提供了很多功能,比如多上传,所以我想使用这个出色的http://blueimp.github.io/jQuery-File-Upload/ 插件。问题是如何像其他表单的数据一样处理“内存中”的文件上传?

例如,当我们显示创建新文章的页面时,我们应该能够填写文章的数据字段并选择要上传的图像,然后当我们单击保存按钮时,图像应该开始上传,然后表单应该提交。当验证失败时,图像仍应显示在前端,但应保存在服务器端 nothink。

其中一个解决方案是在显示整个表单之前创建类似于“创建实体会话临时 ID”的想法,并且该 ID 可用于创建临时目录以保存上传,因此在成功保存表单后,这些图像可以移动到适当的目录,但是如何使“创建实体会话临时id”?

我认为另一种解决方案是“使用编辑 ID”方法,因为我们可以使用以前保存的画廊 ID 处理上传,但有时我无法用画廊保存新的空白文章,因为某些字段应该db 中不能为空。

对于我在自述文件中看到的 https://github.com/thoughtbot/paperclip gem 的 Rails:

Paperclip 旨在作为 Active Record 的简单文件附件库。其背后的目的是使设置尽可能简单,并尽可能像对待其他属性一样对待文件。这意味着它们不会保存到磁盘上的最终位置,如果设置为 nil,它们也不会被删除,直到调用 ActiveRecord::Base#save。

我的问题是它是如何工作的?

【问题讨论】:

    标签: php symfony upload jquery-file-upload


    【解决方案1】:

    在创建掩码上启用文件上传的问题是您最终会得到孤立文件。这是因为用户能够在不保存实际实体的情况下触发上传。在创建一个自己的 UploadBundle 时,我考虑了这个问题一段时间,得出的结论是没有真正合适的解决方案。

    我最终是这样实现的:

    鉴于我们的问题是由孤立文件引起的,我创建了一个Orphanage 来负责管理这些文件。上传的文件将首先与 session_id 一起存储在单独的目录中。这有助于区分不同用户的文件。提交表单以创建实际实体后,您可以仅使用会话 ID 从孤儿院检索文件。如果表单有效,您可以将文件从临时孤儿院目录移动到文件的最终目的地。

    这种方法有一些缺陷:

    • 应使用 cron 作业等定期清理孤儿院目录本身。
    • 如果用户上传文件并选择不提交表单,而是从新表单重新开始,则新上传的文件将被移动到同一目录中。因此,您将获得第一次上传的文件和第二次上传的文件。

    这不是这个问题的最终解决方案,而是一种解决方法。但在我看来,它比使用临时实体或基于会话的存储系统更干净。

    上述捆绑包在 Github 上可用,并支持 OrphanagejQuery File Uploader 插件。

    1up-lab/OneupUploaderBundle

    【讨论】:

    • 嗯,这个捆绑包很有趣。我正在尝试将它与您的建议一起使用,但是如何在 UploadListener 中获取带有 gaufrette 的上传图像的网址?
    • 我猜你必须知道 Gaufrette 存储的基本 url。之后,您可以通过对从事件中检索到的文件使用 getKey 方法来获取文件的目录和路径,并将这两个信息组合到单个 Web 路径中。 (github.com/KnpLabs/Gaufrette/blob/master/src/Gaufrette/…)
    • 是否有任何服务可以自动在 gaufrette 中查找文件的真实路径?我看不到。在树枝助手中的 VichUploaderBundle 中:github.com/dustin10/VichUploaderBundle/blob/master/Templating/… 有特殊的属性映射服务,可以从配置中构建该路径...我相信有更简单的解决方案...
    • 解析到这一点:github.com/dustin10/VichUploaderBundle/blob/master/Mapping/…。据我所知,您可以通过添加uri_prefix 来注释您的实体。我可以看到这更简单,但它肯定不干净。我建议构建一个解析器服务,其中包含构建 url 的逻辑。将其注入您的UploadListener 以供以后使用。
    【解决方案2】:

    我没有亲自处理此案,但我的同事也有类似的难题。她用了

    punkave/symfony2-file-uploader-bundle

    这是一个包裹 jQuery File Upload 插件的包。它处于早期阶段,缺少很多东西,例如事件,但我们试了一下。

    这就是我们所做的:在 newAction() 中,我们创建实体,生成唯一的 dir ID,并将 ID 存储在实体中(通过常规 setDirId())。比我们创建包含隐藏字段 dirId 的表单。

    我们正在通过 ajax 将文件上传到服务器上的临时目录,而不是在提交期间。 Ajax 请求需要 ID。它将文件存储在 temp_dir/prefix_ID

    这很简单。表格已发送。如果表单有效 - 将文件从 temp 移动到 dest 目录。如果没有 - 我们有 ID,并且能够显示图像。

    但是,我们不会将有关单个文件的信息保存在数据库中的单独表中。每次我们读取与我们的 dirId 对应的文件夹的内容时。

    我知道这不是您要求的解决方案。这是一种解决方法。

    【讨论】:

    • 我不推荐这个捆绑包,它在early stage 中已经有一年多了。如果你仔细看看它的 UploaderClass 你会发现,它没有使用任何 symfony 标准。
    • 你是对的。与同事交谈后,发现这个捆绑包并不是很有帮助。最后,她编写了自己的专用解决方案,仅基于 punkave bundle。很抱歉造成混乱。
    猜你喜欢
    • 1970-01-01
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 2021-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多