gpt4 book ai didi

php - 通过 php 上传大文件 ( 0 - 5GB ) 的有效方法

转载 作者:搜寻专家 更新时间:2023-10-31 20:39:49 24 4
gpt4 key购买 nike

我一直在寻找一个好的方法,我一直在用头撞墙。

在一个文件共享服务项目中,我被指派确定上传大文件的最佳方法。

在 stackoverflow 和其他论坛上搜索了很多问题之后,这是我得到的:

  1. 增加脚本的最长执行时间,以及允许的最大文件大小

    这个案子真的不合适。每次通过普通宽带连接(1mbps-2mbps)上传文件时,它几乎都会超时。即使上传完成后执行PHP脚本,也不能保证上传不会超时。

  2. 分块上传。

    虽然我有点明白我应该在这里做什么,但我感到困惑的是,假设正在上传一个 1GB 的文件,而我正在以 2MB 的 block 读取它,但如果上传很慢,php脚本执行会超时报错。

  3. 使用其他语言,如 Java 和 Perl?

    使用java或perl处理文件上传真的高效吗?

客户端使用的方法不是这里的问题,因为我们将发布一个客户端SDK,并且可以在其中实现我们选择的方法。客户端和服务器端的实现都将由我们决定。

考虑到内存使用效率应该很高,并且可能有许多并发上传正在进行,您认为哪种方法应该是最好的?

Dropbox 和类似的云存储服务如何处理大文件上传并保持快速处理?

最佳答案

我建议您将 PHP I/O 流与 AJAX 结合使用。这将使服务器上的内存占用量保持在较低水平,并且您可以轻松构建异步文件上传。请注意,这使用了仅在现代浏览器中可用的 HTML5 API。

查看这篇文章:https://web.archive.org/web/20170803172549/http://www.webiny.com/blog/2012/05/07/webiny-file-upload-with-html5-and-ajax-using-php-streams/

在此处粘贴文章中的代码:

HTML

<input type="file" name="upload_files" id="upload_files" multiple="multiple">

JS

function upload(fileInputId, fileIndex)
{
// take the file from the input
var file = document.getElementById(fileInputId).files[fileIndex];
var reader = new FileReader();
reader.readAsBinaryString(file); // alternatively you can use readAsDataURL
reader.onloadend = function(evt)
{
// create XHR instance
xhr = new XMLHttpRequest();

// send the file through POST
xhr.open("POST", 'upload.php', true);

// make sure we have the sendAsBinary method on all browsers
XMLHttpRequest.prototype.mySendAsBinary = function(text){
var data = new ArrayBuffer(text.length);
var ui8a = new Uint8Array(data, 0);
for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);

if(typeof window.Blob == "function")
{
var blob = new Blob([data]);
}else{
var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
bb.append(data);
var blob = bb.getBlob();
}

this.send(blob);
}

// let's track upload progress
var eventSource = xhr.upload || xhr;
eventSource.addEventListener("progress", function(e) {
// get percentage of how much of the current file has been sent
var position = e.position || e.loaded;
var total = e.totalSize || e.total;
var percentage = Math.round((position/total)*100);

// here you should write your own code how you wish to proces this
});

// state change observer - we need to know when and if the file was successfully uploaded
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4)
{
if(xhr.status == 200)
{
// process success
}else{
// process error
}
}
};

// start sending
xhr.mySendAsBinary(evt.target.result);
};
}

PHP

// read contents from the input stream
$inputHandler = fopen('php://input', "r");
// create a temp file where to save data from the input stream
$fileHandler = fopen('/tmp/myfile.tmp', "w+");

// save data from the input stream
while(true) {
$buffer = fgets($inputHandler, 4096);
if (strlen($buffer) == 0) {
fclose($inputHandler);
fclose($fileHandler);
return true;
}

fwrite($fileHandler, $buffer);
}

关于php - 通过 php 上传大文件 ( 0 - 5GB ) 的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25350089/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com