使用PHP进行大文件上传

37

我想允许我们的 PHP 应用程序上传非常大的文件(几百兆字节至8吉字节)。然而,这里面有一些问题。

浏览器:

  • HTML 上传反馈很差,我们需要轮询上传进度(有点傻),或者根本不显示反馈信息
  • Flash 上传器在开始上传之前将整个文件放入内存中

服务器:

  • PHP 强制我们设置 post_max_size,这可能导致易受攻击的 DOS 攻击。我不想全局设置此选项。
  • 服务器还需要一些其他变量在 POST 变量中,例如一个秘密密钥。我们希望能够立即拒绝请求,而不是在整个文件上传后再拒绝请求。

要求:

  • HTTP 必须支持。
  • 客户端技术我很灵活,只要它在浏览器中运行就可以。
  • 如果有其他在 Linux 环境下工作良好的技术,PHP 不是必需的,那就很好。

1
如果PHP内部不缓冲整个输入,您可以编写一个模块,在POST正文之前检查标头中的ID与数据库中的ID是否匹配。在另一个端口上运行特殊服务器,并从主Web服务器生成ID。 - Aiden Bell
我想看看当许多网络用户同时上传8GB文件时会发生什么。 - Elzo Valugi
@ElzoValugi:这是一个认真的问题吗?如果是,也许你可以稍微改一下措辞,这样我就可以帮你回答了。 - Evert
1
好的,所以这是一种不友善的讽刺意味。明白了。幸运的是,我已经成功地在'09解决了这个问题。 - Evert
1
pluploader非常适合这个任务。因为它默认将上传分块为1MB,所以您可以绕过PHP大小限制。 - artfulrobot
显示剩余7条评论
13个回答

0

我已经成功地使用了uploadify,并且我会推荐它。这是一个处理大型上传的jQuery/Flash脚本,您可以向其传递额外的参数(如秘密密钥)。要解决服务器端问题,只需使用以下代码。更改仅在调用它们的脚本中生效:

//Check to see if the key is there
if(!isset($_POST['secret_key']) || !isValid($_POST['secret_key']))
{
    exit("Invalid request");
}
function isValid($key)
{
    //Put your validation code here.
}

//This line changes the timeout.
//Give it a value in seconds (3600 = 1 hour)
set_time_limit(3600);

//Set these amounts to whatever you need.
ini_set("post_max_size","8192M");
ini_set("upload_max_filesize","8192M");

//Generally speaking, the memory_limit should be higher
//than your post size.  So make sure that's right too.
ini_set("memory_limit","8200M");

编辑 针对您的评论:

根据您所说,恐怕您无法通过http满足您的要求。所有的解决方案都是添加功能到http上,而这些功能并不是它设计的。

就像您自己所说的,它是一个简单的协议。除了编写自己的客户端软件以在浏览器外运行、使用Java小程序或使用不同的协议(如FTP,专门为此设计)之外,您可能无法得到想要的结果。

在给定的限制条件下,我已尽力而为。很抱歉我不能做得更好。


Flash不太好用,请阅读上面的评论。在脚本已经启动后设置upload_max_filesize和post_max_size将没有任何效果。 - Evert

0

很不幸,Flash 一直存在问题。上传前,Flash 会将整个文件放入内存中,导致我的 Mac 完全冻结了几分钟 :( - Evert
Flash中的FileReference类不允许直接访问文件,只能上传。 - Evert
1
这些安全层真讨厌 ;P - Aiden Bell

-2
试试这个:http://www.simple2ftp.com 使用一个基于Java的FTP小程序,嵌入到一个聪明的PHP应用程序包装器中。

"HTTP是必须的"...但这不是基于FTP吗? - Tonny Madsen

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