在PHP中使用分块上传1GB文件

45

我有一个Web应用程序,可以接受最多4MB的文件上传。服务器端脚本是PHP,Web服务器是NGINX。许多用户要求大幅增加此限制,以允许上传视频等。

然而对于这个PHP问题似乎没有简单的解决方案。首先,在客户端,我正在寻找一些可以在传输期间分块文件的东西。SWFUpload似乎没有这样的功能。我猜想我可以使用Java FX(http://blogs.oracle.com/rakeshmenonp/entry/javafx_upload_file)流式上传,但我无法找到PHP中request.getInputStream的任何等效方法。

增加浏览器client_post限制或php.ini上传或max_execution时间对于非常大的文件(~1GB)并不是真正的解决方案,因为浏览器可能会超时,并考虑所有存储在内存中的数据块。

是否有任何方法可以使用PHP在服务器端解决这个问题?我会感激您的回复。


3
我的一个应用程序允许通过配置与您提到的相同的服务器端选项上传大小超过1 GB的文件。用户从未报告过任何超时等问题。 - Dolph
2
一个好的解决方案应该在任何地方都能够正常工作。使用56 KBPS调制解调器或缓慢的连接上传1GB文件将不起作用。分块解决方案将非常健壮,并且可以支持恢复中断的链接。 - rjha94
1
请看这里:https://tus.io/ - sgargel
8个回答

15

plupload 是一个JavaScript/PHP库,非常易于使用并支持分块上传。

它使用HTML5技术。


值得一提的是,同时它也支持HTML4、Silverlight和Flash,可以在这里看到:http://www.plupload.com/example_all_runtimes.php。 - jdepypere

4
请查看tus协议,它是一种基于HTTP的协议,用于可恢复文件上传,这样在任何中断情况下,您可以从上次离开的地方继续进行,而无需重新上传整个数据。自2017年5月起,该协议还被vimeo采用
您可以在此处找到不同语言的各种实现。在您的情况下,您可以使用其JavaScript客户端uppy,并在服务器上使用基于golangphp的实现。

找不到示例,它是否允许设置请求头? - TheRealChx101
是的,您可以使用tus中间件添加请求头:https://github.com/ankitpokhrel/tus-php#middleware 您可以在此处找到示例实现:https://github.com/ankitpokhrel/tus-php/tree/master/example - Konsole

3

但是我在PHP中找不到类似于request.getInputStream的等效方法。

fopen('php://input'); 可能是一个选择?


不要在多部分表单数据中使用php://input。 - rjha94

3

我创建了一个JavaFX客户端,用于以最大POST大小(我使用的是2 MB)的块发送大型文件,并使用PHP接收器脚本将这些块组装成原始文件。我在此处发布代码,采用Apache许可证:http://code.google.com/p/gigaupload/。欢迎自由使用、修改和分发。


如果这解决了您的问题,请毫不犹豫地将其标记为答案;-) - MartyIX

2

尝试使用bigupload脚本。它非常容易集成,并且可以分块上传高达2 Gb的文件。分块大小可以自定义。


5
链接失效。 - machineaddict
请返回翻译后的文本:在此处查看https://searchcode.com/file/71374260/inc/bigUpload.php/ - Amjad Farooq

0

谢谢提供链接。这应该是可能的,我现在正在尝试使用Java FX。JUpload的截图看起来好像是10年前的事情了;o) - rjha94
哈哈,我不确定啊 :) 但是这个PHP代码很新(最近几天更新的),你可以看看他们如何进行分块处理。http://jupload.svn.sourceforge.net/viewvc/jupload/trunk/wwwroot/samples.PHP/jupload.php?view=markup - Chris

0

你可以使用这个软件包

它支持可恢复的分块上传。

examples/js-examples/resumable-chunk-upload示例中,您可以关闭并重新打开浏览器,然后继续未完成的上传。


-1
你绝对可以编写一个 Web 应用程序,它将接受一块数据(甚至通过 POST),然后将该数据块附加到文件中。在我看来,你需要某种客户端应用程序,它将把文件分成块,然后一次发送一个块到你的 Web 服务。但是,创建一个 sftp 目录并让客户端使用一些现有的客户端应用程序上传文件似乎更容易。

2
你可能不想在每个块到达时将其附加到目标文件中。这些块可能会失去顺序。我们使用的解决方案是为每个块保存一个数字ID,然后在所有块都上传完毕后将它们组合起来。 - rodrigo-silveira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接