HTML5になるとローカルファイルをブラウザにドラッグしてアップロードできるで書いたように、HTML5対応でないブラウザを考慮すると、従来通りファイル選択ダイアログから画像を選ばしてアップロードするというアプローチになります。
しかし、通常はアップロードファイルをファイル選択してもブラウザにはファイル名が出るだけです。
今回やってみるのは、ファイル選択したら画像を非同期(Ajax)でアップロードし、サムネイルを表示する方法です。
jQuery と AjaxUpload を使います。
AjaxUploadは元来、http://valums.com/ajax-upload/で公開されたらしいのですが、現在は FileUploader という新しいものになっているようです。
で、解説サイトAjax Upload - ZURB Playground - ZURB.comからAjaxUploadをダウンロードします。
使い方は下記のような感じです。
●クライアント側
・HTMLファイル
"Content-Type" content="text/html; charset=UTF-8">
.loading{background-image: url("./images/load.gif")
}
.no_display{
display: none;
}
HTMLの規約上、formはネストさせてはいけないので、メインのformとは別に定義する必要があります。(ネストさせるとうまく動きませんでした。
JavaScriptでAjaxUploadのインスタンスを作成し、参照ボタンでファイルを選んだらサーバに送信し、その後、サーバからレスポンスで画像ファイルへのパスを取得し表示します。
ただ、上記の方法だとメインフォーム送信時に、参照ボタンで選んだ画像ファイルを送ることはできません。
なので、AjaxUploadでアップロードされたファイルパスをhiddenに持ち、そのアップロードファイルパスをメインフォーム送信先に送るような仕組みにしています。
$uploaddir = './uploads/';//画像更新時に発生するブラウザキャッシュの問題を回避したければ、timme() でUnixタイムスタンプをつけたほうが良いかも。
$file = $uploaddir . basename($_FILES['image']['name']);
//画像かどうか
$imginfo = getimagesize( $_FILES['image']['tmp_name'] );
if ( $imginfo[2] == IMAGETYPE_JPEG || $imginfo[2] == IMAGETYPE_GIF
|| $imginfo[2] == IMAGETYPE_PNG ){
//画像の時
if (move_uploaded_file($_FILES['image']['tmp_name'], $file)) {
echo $uploaddir . $_FILES['image']['name'];
} else {
echo $uploaddir . "err.jpg";
}
}else{
//画像じゃないとき
echo $uploaddir . "err_nonimg.jpg";
}
PHP側では送信されてきたファイルが画像ファイルかどうか判断し、画像ファイルならアップロードディレクトリにコピーします。
そして、ファイルパスをクライアントに返します。
ただ、一回画像をアップロードし、再度参照ボタン押下して別画像に更新しようとすると、ブラウザキャッシュのせいで、画像自体はアップロードされているものの、ブラウザ表示上は変わらない現象が発生しました。(HTTPヘッダでキャッシュ無効にしてもダメでした。)
なので、ファイル名にUnixタイムスタンプを含めるなどの手法を取り、ファイル名が同一にならないようにしたほうが良いかもしれません。
参考:
画像アップロード時にjQueryでサムネイルを表示する方法 | Web活メモ帳
AJAX Multiple File Upload Form Using jQuery