人気ブログランキング |
(PHP,HTML)AjaxUpload 画像選択時にアップロードしサムネイルを表示
HTML5になるとローカルファイルをブラウザにドラッグしてアップロードできるで書いたように、HTML5対応でないブラウザを考慮すると、従来通りファイル選択ダイアログから画像を選ばしてアップロードするというアプローチになります。

しかし、通常はアップロードファイルをファイル選択してもブラウザにはファイル名が出るだけです。

今回やってみるのは、ファイル選択したら画像を非同期(Ajax)でアップロードし、サムネイルを表示する方法です。


jQuery と AjaxUpload を使います。

AjaxUploadは元来、http://valums.com/ajax-upload/で公開されたらしいのですが、現在は FileUploader という新しいものになっているようです。

で、解説サイトAjax Upload - ZURB Playground - ZURB.comからAjaxUploadをダウンロードします。

使い方は下記のような感じです。

●クライアント側
・HTMLファイル
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="jquery-1.6.2.js"></script>
<script type="text/javascript" src="ajaxupload.js"></script>
</head>
<body>
<!-- ↓AjaxUploadを使うためのスクリプト。画像を非同期でアップし、完了したらサムネイル表示 -->
<script type="text/javascript" charset="utf-8">
$(function(){
//サムネイル表示するimgタグを ID 名で指定(jQueryを使ったセレクタ)
var thumb = $('img#thumb');
var imagefilename = $("#imagefilename");
//AjaxUploadクラスを生成し、参照ボタン押下時の処理を定義。第一引数は参照ボタンのID名。
new AjaxUpload('imageUpload', {
//formタグのID名 newHotnessForm を実行
action: $('form#newHotnessForm').attr('action'),
name: 'image',
//アップロード中は loading スタイルシートを利用
onSubmit: function(file, extension) {
$('div.preview').addClass('loading');
},
//アップロード完了時の処理
onComplete: function(file, response) {
thumb.load(function(){
$('div.preview').removeClass('loading');
thumb.unbind();
});
thumb.attr('src', response);
//img要素表示
thumb.css("display", "inline");
//hiddenに画像パス指定
$("#imagefilename").attr("value" , response);
/*デバッグ。Ajaxで返された値を表示。*/
$("#res").html(response);
}
});
<!-- ↓クリアボタン押下時の設定 -->
$("#pic1_clear").click(function(){
thumb.removeAttr('src');
thumb.css("display", "none");
imagefilename.attr("value" , "");
});

});

</script>

<form id="hoge" method="post" action="hoge.php"><!-- ←メインのフォーム -->
氏名:<input type="test" id="name" name="name" size="20"><br>
写真1:<input type="file" id="imageUpload" name="imageUpload" size="20"><br>
<!-- ↓に上記参照ボタンで選んだ画像ファイルが表示される。 -->
<div class="preview">
<img id="thumb" width="320px" height="240px" class="no_display" >
<!-- 参照ボタンで画像選択時に、アップロードされた画像パスを保持し、メインのフォーム先に送信 -->
<input type="hidden" id="imagefilename" name="imagefilename" >
</div>
<!-- デバッグ用。Ajaxで返された値を表示 --><div id="res"></div>
<input type="submit" value="登録">
</form>

<!-- ファイル選択参照ボタン押下時に動くフォーム -->
<form id="newHotnessForm" method="post" action="./upphp.php">
</form>

</body>
</html>



・スタイルシート
.loading{
background-image: url("./images/load.gif")
}
.no_display{
display: none;
}


HTMLの規約上、formはネストさせてはいけないので、メインのformとは別に定義する必要があります。(ネストさせるとうまく動きませんでした。
JavaScriptでAjaxUploadのインスタンスを作成し、参照ボタンでファイルを選んだらサーバに送信し、その後、サーバからレスポンスで画像ファイルへのパスを取得し表示します。
ただ、上記の方法だとメインフォーム送信時に、参照ボタンで選んだ画像ファイルを送ることはできません。
なので、AjaxUploadでアップロードされたファイルパスをhiddenに持ち、そのアップロードファイルパスをメインフォーム送信先に送るような仕組みにしています。


●PHPサーバ側(upphp.php)
$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
php で画像ファイル形式を判別する方法 - ブックマクロ開発に
PHP関数講座:getimagesize -- そふぃのphp入門
by Jehoshaphat | 2012-10-22 01:31 | PHP開発


<< (Linux)普通のsamba... (JavaScript)jQu... >>