2013-05-18 40 views
8

所以我希望用户能够上传大文件而不必担心后期最大大小值。 另一种方法是使用PUT并将文件作为原始数据发送。由于把整个文件到一个变量形式边界和编写php://输入到php中的文件

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

: 当使用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"); 

我没有做上传大文件时肯定会填满所有内存。

我无法弄清楚的是如何在没有窗体边界的情况下编写文件数据。 现在它写在文件是这样的顶部:

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

,并在底部是这样的:

------WebKitFormBoundaryVz0ZGHLGxBOCUVQG--  

所以我需要解析的数据。但为此,我需要将整个数据流读入内存,并且我不想那么做。 我没有读过关于创建一个php:// temp流的信息。但没有运气,但与此。 如何在没有边界头的情况下将内容写入文件?没有首先将所有数据抽入变量?

+0

你能否提供'Content-Type'头文件? –

回答

1

可能的fgets组合停止阅读在换行和检查的界限:

while($kb = fgets($s, 1024)) 
{ 
    if(strpos($kb, '------') === false) //or !== 0 for first position 
    { 
     fwrite($f, $kb, 1024); 
    } 
} 
+0

但是如何确定'-----'是否包含在同一块中?如果“---”包含在第一个块的末尾和“---”中,那么该怎么办?这是第二个块的开始?或者它不可能是这种情况? – Tamara

+0

'fgets'读到行'\ n'的末尾,所以 - 会在下一行的开头。 – AbraCadaver

+0

如果是这样的话,下面的头文件会发生什么?他们也会损坏文件。 –

1

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

它还包括您需要在服务器端的PHP code

+0

我在几个有很多上传文件的网站上使用blueimp上传器,它对我的​​用户来说效果很好。 –

0

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

使用的.htaccess或您的apache.conf

php_value upload_max_filesize 10G 
php_value post_max_size 10G 

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

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