--- title: 【PHP】大きいサイズファイルのHTTPアップロード tags: PHP author: tenda_chi slide: false --- ##1.通常のやり方 1. php設定値を大きく設定して - upload_max_filesize = 500M - post_max_size = 500M - max_input_time = 300 - max_execution_time = 300 2.Client-Side HTML. enctype="multipart/form-data"とする。 test upload
ファイル:
3.Server-Side PHP if(is_uploaded_file($_FILES['myfile']['tmp_name'])){ if(move_uploaded_file($_FILES['myfile']['tmp_name'],"./".$_FILES['myfile']['name'])){ echo "upload successed."; }else{ echo "error save file."; } }else{ echo "error upload file."; } //laravel $dir_path = storage_path('app/debug'); $file = Request::file('myfile'); $name = $file->getClientOriginalName(); $move = $file->move(dir_path,$name); 通常やり方の問題点 - PHPの色んな設定値を気にしないといけない。 - 場合によってHTTPサーバーの設定値も調整する必要がある。 - Nginx: client_max_body_size 100m; - Tomcat: maxPostSize="10485760" - Apache: LimitRequestBody=0 - ファイルサイズが数GBを超えると何れ何処の壁とぶつかる。 ##2.ファイルを分割して複数回リクエストでアップロードする方法 ###TUS resumable upload protocol https://tus.io/ ファイルアップロード途中でブラウザを再読み込みするなどして、強制中断した後に、同じファイルをアップロードすると、中断時点からアップロード処理を再開することができます。 ###Demo https://tus.io/demo.html ###Tusとは tusは、再開可能なファイルのアップロードを簡単に使用でき、広く利用できるようにすることを目的としたプロジェクトです。 このプロジェクトの最も興味深い部分は、プロトコル仕様と多くの自由に利用可能なクライアントとサーバーの実装です。 ###主な特徴 - HTTP-based HTTPプロトコルの上にレイヤーとして構築されたtusは、既存のライブラリ、プロキシ、ファイアウォールを使用してアプリケーションに簡単に統合でき、任意のWebサイトから直接使用できます。 - Production-ready tusはプロダクション環境にも安心的に利用可能です。何度も改善され、Vimeo、Google、その他の複数の有名企業で働く人々から貴重なフィードバックを受けています。 - Open source MITライセンスでの利用が可能。https://github.com/tus - Minimalistic design... ClientとServerに少ないコードを実装をするだけで利用可能。tusは、すべての人にシンプルさ、迅速な開発、イテレーション速度を提供します。 - ... yet still extensible tusには、並列アップロードやチェックサムと有効期限などの追加機能を導入する拡張機能のかなりのリストがあります。これらはすべて、好みに応じて実装できます。 - Community-owned このプロトコルのオープンでアクセス可能な進化を信じています。 tusの開始以降のどの段階でも、フィードバックは高く評価され、統合されています。あなたの貢献も楽しみにしています。 ###Server-Side PHP 1.Installation `$ composer require ankitpokhrel/tus-php` 2.Laravel Integration 新しいserviceProviderを作成する。 namespace App\Providers; use TusPhp\Tus\Server as TusServer; use Illuminate\Support\ServiceProvider; class TusServiceProvider extends ServiceProvider { // ... /** * Register the application services. * * @return void */ public function register() { $this->app->singleton('tus-server', function ($app) { $server = new TusServer('redis'); $server->setApiPath('/tus') // tus server endpoint. ->setUploadDir(storage_path('app/public/uploads')); // uploads dir. return $server; }); } // ... } Routing設定 Route::any('/tus/{any?}', function () { $response = app('tus-server')->serve(); return $response->send(); })->where('any', '.*'); CSRF validationを除外する // ... class VerifyCsrfToken extends BaseVerifier { // ... protected $except = [ '/tus', '/tus/*', ]; } ###Client-Side 1.Vue 版 `$ npm install tus-js-client` 2.JS版 input.addEventListener("change", function(e) { // Get the selected file from the input element var file = e.target.files[0] // Create a new tus upload var upload = new tus.Upload(file, { endpoint: "/tus", retryDelays: [0, 3000, 5000, 10000, 20000], metadata: { filename: file.name, filetype: file.type }, onError: function(error) { console.log("Failed because: " + error) }, onProgress: function(bytesUploaded, bytesTotal) { var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2) console.log(bytesUploaded, bytesTotal, percentage + "%") }, onSuccess: function() { console.log("Download %s from %s", upload.file.name, upload.url) } }) // Start the upload upload.start() }) 3.進捗を見える化 onProgressのeventを利用して画面側にプログレスバーの表示は可能です。 ##参考URL https://tus.io/ https://github.com/ankitpokhrel/tus-php https://github.com/tus/tus-js-client 以上