5

私は良い方法を探していて、頭を壁にぶつけていました。

ファイル共有サービス プロジェクトで、大きなファイルをアップロードするための最適な方法を決定する任務を負っています。

ここでスタックオーバーフローや他のフォーラムで多くの質問を検索した後、ここに私が得たものがあります:

  1. 許可される最大ファイル サイズとともに、スクリプトの最大実行時間を増やします

    このケースは本当に似合いません。ファイルが通常のブロードバンド接続 (1mbps-2mbps) を介してアップロードされているときは、ほぼ毎回タイムアウトします。アップロード後に PHP スクリプトを実行しても、アップロードがタイムアウトしないという保証はありません。

  2. チャンクアップロード。

    ここで何をすべきかはある程度理解できますが、混乱しているのは、1 GB のファイルがアップロードされていて、それを 2 MB のチャンクで読んでいるとします。 PHP スクリプトの実行がタイムアウトし、エラーが発生します。

  3. Java や Perl などの他の言語を使用しますか?

    ファイルのアップロードを処理するために Java や Perl を使用するのは本当に効率的ですか?

ここではクライアントが使用するメソッドは問題ではありません。クライアント SDK を発行し、その中で選択したメソッドを実装できるからです。クライアント側とサーバー側の両方の実装は、私たちが決定します。

メモリ使用量が効率的であるべきであり、多くの同時アップロードが行われている可能性があることを考えると、どの方法が最適であると思いますか?

Dropbox や同様のクラウド ストレージ サービスは、どのようにして大きなファイルのアップロードを処理し、高速に維持しているのでしょうか?

4

2 に答える 2

5

AJAX で PHP I/O ストリームを使用することをお勧めします。これにより、サーバーのメモリ フットプリントが低く抑えられ、非同期ファイル アップロードを簡単に作成できます。これは、最新のブラウザーでのみ使用できる 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);
}
于 2014-08-17T16:06:19.500 に答える