こんばんは、martinです。以前、Flex(Flash)を用いた複数ファイルのアップローダー
を紹介しましたが、実はHTML5だけで出来るのになぁ、と思っていました。現時点で、IE8を除く主要なブラウザでは軒並み、HTML5のINPUT要素に対するmultiple属性に対応しているので、それによる実装をppBlogに施してみました。複数ファイルを選択可能にするには、input要素にmultipleを指定するだけです。
<input type="file" name="src[]" id="src" multiple />
とりあえず実装してみただけですが、きちんと動作しました(ここのエントリー
は画像を複数枚一度にアップロードした)。UIをどうするかで試行錯誤しましたが、プロトタイプにしてはまぁまぁかなと思っています。

さて、複数の(画像)ファイルがアップロード出来るようになると、アップロードする枚数に応じて、サーバーにデータを渡す間、じっと待たされるようになります。現状、HTML5のみではぼーっと待つしかありません
なので、アップロードの進捗状況を示すプログレスバーが欲しくなります。この手のスクリプトはウェブ上にいろいろありますが、どれもFlashを用いたり、Perl(+JavaScript)を用いたりしたものです。出来ればPHP(+JavaScript)のみで完結させたい。
いろいろ調べてみると、PHPとJavaScriptのみでは、ファイルアップロードに伴なうプログレスバーのギミックを提供するのは無理という記述ばかりです。というのもPHPには、ファイルアップロードの途中経過を知らせる仕組みが備わっていないからです。実は、PHP5.2以上であれば、PECL APC拡張機能を組み込んで可能
なのですが、サーバー側で PECL APCエクステンションをインストールする必要があり、これはレンタルザーバー等では敷居が高いでしょう。
- サーバー上に転送される(画像)データは、最初は一時的なディレクトリ(テンポラリディレクトリ)にアップロードされます。この一時的なディレクトリは、だいたい/tmpディレクトリのことが多いです。php.iniで指定可。
- 画像データの転送が無事に終わると、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となります。具体的なデモ
を見てみましょう。うまく行けば、転送中のブラウザ画面は下のようなスクリーンショットになります。Firefox3.6.3やSafari, Google Chromeの最新版で動くと思います。

|martin|1|1|||
[1] => 1152120960|開発日誌|リスト表示ならAjaxで読み込み| リスト表示のときは、Ajax経由で記事を読み込んで表示させるという感じにしてみました。細かいところの詰めなどあると思いますが、雰囲気は味わえると思います。やっぱり、Ajaxを使うと記事のデータだけをダウンロードするので、ページ全体を読み込むのに比べて表示が速いですね。`` このギミックについて何かアイデアなり、希望などがあればコメントお願いします。|martin|1|1|JavaScript||
[2] => 1151498116|開発日誌|Ajaxによる自動投稿スクリプト| フォーラムで,一旦投稿した後に,引き続き編集作業を継続できないかという問い合わせがありました。ppBlogでは,公開される通常の投稿であれ非公開のドラフト投稿であれ,ポストした後は一旦トップページを表示するような流れになっている訳ですが,確かに,そんなのもありだなぁと思った次第。編集画面から投稿後のトップページへの切り替えはJavaScriptを使っていて,とりあえずは,この行き先を変更すれば,投稿後に編集画面に戻ることが出来ます。これはnaoKさんが解決法をフォーラムの方に書いてくれてます。` →http://forum.p2b.jp/index.php?mode=box&UID=2870&display=all`` で,ppBlogは[w]AJAX[/w]の技術をコメント表示などに用いており,またログイン認証ではAJAXでポストということもしています。なので,記事の投稿もAJAX経由でいけば,編集画面から離れることなく,バックグラウンドでのドラフト投稿が出来そうだと思い,スクリプトを書いてみました。`` まずは,AJAX経由でポストするので,そのための準備をします。POST送信で送るパラメータは Array.push() メソッドを用いて,どんどん追加していって,最後に Array.join('&') で連結すればOKです。これをppBlogに組み込まれているAjax.post()メソッドを使ってPOST送信すれば良いです。これは以下のような感じになります(細かな条件振りなどは省略して書いています)。``
`
`














Comments