10

所以我希望用户能够上传大文件,而不必担心帖子的最大大小值。另一种方法是使用 PUT 并将文件作为原始数据发送。使用 jquery 时,我可以这样做:

var data = new FormData();
  jQuery.each($('#file_upload')[0].files, function(i, file) {
  data.append('file-'+i, file);
});
$.ajax({
  url: 'upload.php?filename=test.pdf',
  data: data,
  cache: false,
  contentType: false,
  processData: false,
  type: 'PUT',
});

在 PHP 中,我可以这样做:

$f = fopen($_GET['filename'], "w");
$s = fopen("php://input", "r");

while($kb = fread($s, 1024))
{ 
  fwrite($f, $kb, 1024); 
}
fclose($f);
fclose($s);
Header("HTTP/1.1 201 Created");

我没有做:

$client_data = file_get_contents("php://input");

由于将整个文件放入变量中肯定会在上传大文件时填满所有内存。

我无法弄清楚的是如何在没有表单边界的情况下写入文件数据。现在它在文件顶部写了这样的内容:

------WebKitFormBoundaryVz0ZGHLGxBOCUVQG
Content-Disposition: form-data; name="file-0"; filename="somename.pdf"
Content-Type: application/pdf

在底部是这样的:

------WebKitFormBoundaryVz0ZGHLGxBOCUVQG--    

所以我需要解析数据。但为此,我需要将整个数据流读入内存,并且对于大型视频文件,我不想这样做。我确实读过一些关于可能创建 php://temp 流的内容。但还没有运气。如何在没有边界标题的情况下仅将内容写入文件?并且没有先将所有数据注入变量?

4

3 回答 3

1

你可以使用这个(有很多喜欢的)。它支持分块上传,这意味着只要每个上传块小于帖子最大大小,您就不会达到任何帖子/文件的最大大小。

它还包括您在服务器端需要的PHP 代码。

于 2015-02-06T17:54:43.553 回答
1

也许是fgets在换行符处停止阅读并检查边界的组合:

while($kb = fgets($s, 1024))
{ 
    if(strpos($kb, '------') === false) //or !== 0 for first position
    {
        fwrite($f, $kb, 1024); 
    }
}
于 2015-02-03T21:56:27.550 回答
0

无需重新创建轮子。只需使用 POST 并将 PHP 的配置更改为更大的限制。这些限制也可以在每个目录/主机的基础上设置。

使用 .htaccess 或你的 apache.conf

php_value upload_max_filesize 10G
php_value post_max_size 10G 

调整其他限制也是一个好主意,例如 max_input_time。

不要忘记使用move_uploaded_file重新定位收到的文件以避免任何额外的工作。

于 2015-02-10T21:43:56.663 回答