HTML5による複数ファイルアップロード

category-icon

 こんばんは、martinです。以前、Flex(Flash)を用いた複数ファイルのアップローダーLink を紹介しましたが、実はHTML5だけで出来るのになぁ、と思っていました。現時点で、IE8を除く主要なブラウザでは軒並み、HTML5のINPUT要素に対するmultiple属性に対応しているので、それによる実装をppBlogに施してみました。複数ファイルを選択可能にするには、input要素にmultipleを指定するだけです。

<input type="file" name="src[]" id="src" multiple />

 とりあえず実装してみただけですが、きちんと動作しました(ここのエントリーLink は画像を複数枚一度にアップロードした)。UIをどうするかで試行錯誤しましたが、プロトタイプにしてはまぁまぁかなと思っています。

shot1
このように一度に複数画像の選択が可能です。

 さて、複数の(画像)ファイルがアップロード出来るようになると、アップロードする枚数に応じて、サーバーにデータを渡す間、じっと待たされるようになります。現状、HTML5のみではぼーっと待つしかありません(-o-) なので、アップロードの進捗状況を示すプログレスバーが欲しくなります。この手のスクリプトはウェブ上にいろいろありますが、どれもFlashを用いたり、Perl(+JavaScript)を用いたりしたものです。出来ればPHP(+JavaScript)のみで完結させたい。

 いろいろ調べてみると、PHPとJavaScriptのみでは、ファイルアップロードに伴なうプログレスバーのギミックを提供するのは無理という記述ばかりです。というのもPHPには、ファイルアップロードの途中経過を知らせる仕組みが備わっていないからです。実は、PHP5.2以上であれば、PECL APC拡張機能を組み込んで可能Link なのですが、サーバー側で PECL APCエクステンションをインストールする必要があり、これはレンタルザーバー等では敷居が高いでしょう。

 なので(Perlはあまり好きになれないという理由もあり)PHPとJavaScriptのみによる実装を考えてみました。まずは、PHPにおける、POST メソッドによるファイルアップロード時の挙動を知る必要があります。マニュアルによれば、基本的に以下の手順を踏みます。
  1. サーバー上に転送される(画像)データは、最初は一時的なディレクトリ(テンポラリディレクトリ)にアップロードされます。この一時的なディレクトリは、だいたい/tmpディレクトリのことが多いです。php.iniで指定可。
  2. 画像データの転送が無事に終わると、move_uploaded_file関数を用いて指定したディレクトリに画像データを移動させます。

 PHPでのネックは、この1番目の進捗状況を知るメソッドが備わっていないことです(なのでこの部分だけはPerlで処理するスクリプトがある)。サーバーサイドで提供しないのであれば、こちらからゲットしに行きましょう。アップロード中のデータは、テンポラリディレクトリに溜まっていくので、そのディレクトリのサイズは徐々に大きくなるはずです。なので、そのディレクトリのサイズを定期的に監視すればOKということになります。この「定期的に監視」という部分にJavaScriptのAjaxを使えば良いわけです。

 ディレクトリのサイズは、以下の記述で取得可能です。
$tmp_dir = '/tmp'; // 取得したいテンポラリディレクトリ

$size = 0; // ディレクトリのサイズ

$d = opendir($tmp_dir);
while($file = readdir ($d)){
 if(is_file($tmp_dir.'/'.$file)){
  $size += filesize($tmp_dir.'/'.$file);
 }
}
closedir($d);
echo($size); // ディレクトリの合計サイズを得る

 なお、上の例では、テンポラリディレクトリは/tmpですが、これを取得したい場合は、ファイルアップロード時に現れる変数の$_FILES['src']['tmp_name']を利用して、

dirname($_FILES['src']['tmp_name']);

で取得可能です。

 あとは、AjaxとPHPで、このディレクトリサイズを返すような記述をして、それをJavaScript側に渡し、プログレスバーっぽく見せればOKとなります。具体的なデモLink を見てみましょう。うまく行けば、転送中のブラウザ画面は下のようなスクリーンショットになります。Firefox3.6.3Safari, Google Chromeの最新版で動くと思います。

progressbar
プログレスバーが表示され、進行状況が一目瞭然。

       


— posted by martin at 01:14 am   commentComment [6]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0032 sec.
prev
2010.4
next
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30