
HTML5のFile APIを使って、複数(の画像)ファイルをサーバにアップロードする方法。
2017/12/09
HTML5のFile APIを使うと、複数ファイルのアップロードが簡単に出来るそうなので、試してみました。
対象のブラウザがモダンブラウザに限定されるようなのですが、妙に簡単に出来たのが印象的。
ちなみに、CakePHP2(2.3.6)でも動きました。
HTML5 File API とは?
File APIとは、今までJavaScriptが直接扱うことが出来なかったローカルファイルに対して、読み取り操作を実現可能にするものです。また、今後の展開としてローカルファイルの書き込みや保存、さらにはWebアプリに専用のファイルシステムをサポートするAPIも、W3Cで標準化作業が進行中です。
IE10で動くHTML5アプリ実装例 「File APIを利用したアプリ」 (1/3):CodeZine
とこのとで、ローカルファイルを扱えるようになった、とのことです。
対象のブラウザは、
- Internet Explorer
- 10以降
- Firefox
- 3.5以降
- Google Chrome
- 6以降
- Safari
- 5以降
- Opera
- 10以降
と、なります。
ただし、SafariではFileReaderオブジェクトを、Internet Explorer 10ではreadAsBinaryStringメソッドをサポートしていません。
テストコード
では、その辺りを踏まえてるのかどうか分かりませんが、実際に動かしてみます。
index.htmlです。
[html]
HTML5 File API
[/html]
単なるフォームを用意しただけです。
upload.phpは、受け取った$_POST内容で画像ファイルをセーブするルーチンです。
注意するのが、ファイルタグの部分。
<input type="file" name="upfile[]" multiple>
- nameを配列とすべく『[]』をつける
- 『multiple』で、複数ファイルを扱えるようにする
という2点が注目するところ。
試しに、3枚のファイルを送信した結果を var_dump()すると、以下のようになります。
なお、複数のファイルを選択する方法はOSによって異なります。
Windowsではctrl+クリック、MacOSではCommand+クリック。あるいは、Shift+クリックで範囲選択することができます。
[php]
array(1) {
["upfile"]=>
array(5) {
["name"]=>
array(3) {
[0]=>
string(12) "6791558.jpg"
[1]=>
string(12) "6795085.jpg"
[2]=>
string(12) "3956c40b.jpg"
}
["type"]=>
array(3) {
[0]=>
string(10) "image/jpeg"
[1]=>
string(10) "image/jpeg"
[2]=>
string(10) "image/jpeg"
}
["tmp_name"]=>
array(3) {
[0]=>
string(27) "C:\Windows\Temp\php2D40.tmp"
[1]=>
string(27) "C:\Windows\Temp\php2D70.tmp"
[2]=>
string(27) "C:\Windows\Temp\php2D71.tmp"
}
["error"]=>
array(3) {
[0]=>
int(0)
[1]=>
int(0)
[2]=>
int(0)
}
["size"]=>
array(3) {
[0]=>
int(96238)
[1]=>
int(44178)
[2]=>
int(89470)
}
}
}
[/php]
PHPerな人たちなら、見覚えのある形式で受信できていますね。
$_POSTで受信できているので、あとは画像を作成すればいいだけです。
とりあえず、以下の様なphpを組んでみました。
[php]
define('FILE_PATH','./image/'); //保存するパスを指定
if ( !empty($_FILES) ) {
for ( $i=0; $i
} else {
echo "アップロードエラー";
}
} else {
echo "アップロードの対象は画像ファイル(.jpg/.gif/.png)のみです。";
}
}
}
}
[/php]
仕様としては、送信された回数分ループを回し、アルファベットのみなファイル名の場合は、
[マイクロ秒]元ファイル名.拡張子 の形式で、
アルファベット以外の文字が含まれるファイル名画像の場合は、
[マイクロ秒]yyyymmdd_hhmmss.拡張子 の形式で保存します。
まぁ、さほど凝ったこともしていないので、もっと良い感じのルーチンが存在すると思います。
実際に試してみる
初期画面
ファイル選択
「017.png」「国会議事堂.png」「上野動物園.png」の3個の複数ファイルを選択中。
選択後画面
Chromeでは、選択すると、個数が表示されます。
アップロード結果
元のファイル名でアップしたファイルを表示しています。
アップロードされた画像
アップロードされている画像。phpで組んだルーチン通り、[マイクロ秒]ファイル名.拡張子の形式で保存されています。
多少、ブラウザ依存になりますが、これで複数ファイルのアップロードが可能になるとは、HTML5、良い感じですよね。
[tgAmazonItemLookup asin="4048862588" related="1"]