『PHP : 選択した画像の表示 / ファイルアップロード ver.2』 よりアップグレードします。 $.ajax と FormData オブジェクト を使用して画像をアップロードします。よって、HTML の FORM での送信は必要なくなります( HTML の入力チェックは必要時に使用する仕様なのでので FORM の記述は必要です )✅ control.php コントローラ ✅ model.php このバージョンでは使用しません ✅ view.php 画面定義 ✅ client.js FileReader オブジェクトを使用した、画像表示 ※ 複数選択が可能になっています ✅ upload.js $.ajax と FormData オブジェクト ✅ uplaod.php move_uploaded_file でアップロードされたファイルを保存するのが主な役割です。 ( 結果は JSON フォーマットで $.ajax に返します ) control.php $image_path は upload.php で使用するので、そちらへ移動しています。 ( $result_message ももう使用しません )
<?php
// 不必要なエラー表示を行わない
error_reporting( E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED );
// ブラウザのキャッシュに保存しない
session_cache_limiter('nocache');
// セッションの開始
session_start();
// この ページの MIME( ページの種類 ) の設定
header( "Content-Type: text/html; charset=utf-8" );
// ***********************************************
// 固有の処理
require_once("model.php");
// $image_path = "./myimages";
// $result_message = "";
// 画面
require_once("view.php");
// デバッグ
//debug_print();
?>
model.php ここは、もう使用しません( 標準化の為、model.php を削除する事はありません )
<?php
// ********************************************
// このアプリケーション専用の処理
// ********************************************
// *******************************************************
// デバッグ
// *******************************************************
function debug_print() {
print "<pre>";
print_r( $_GET );
print_r( $_POST );
print_r( $_SESSION );
print_r( $_FILES );
print "</pre>";
}
?>
view.php 選択するファイルを画像限定にする為に、type="file" の INPUT 要素の属性に accept=".png,.jpg,.jpeg,.gif" を追加しています。また、アップロードを $.ajax で行うので FORM の enctype="multipart/form-data" は削除しています。
<!DOCTYPE html> <html> <head> <meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" name="viewport"> <meta charset="UTF-8"> <title>画像ファイルアップロード</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"> <script src="client.js?_=<?= time() ?>"></script> <script src="upload.js?_=<?= time() ?>"></script> </head> <body> <div id="head"> <div id="title"> <a href="./">画像をアップロード</a> </div> </div> <div id="content"> <form id="frm" method="POST"> <p> <input type="hidden" name="MAX_FILE_SIZE" value="1000000"> <input id="target" name="target" type="file" accept=".png,.jpg,.jpeg,.gif" class="ml-1 mt-3 btn btn-outline-primary"> </p> <p> <input type="submit" name="send" value="アップロード" class="ml-1 btn btn-outline-primary"> <a class="ml-4 btn btn-info btn-sm" href="<?= $_SERVER["PHP_SELF"] ?>">リロード</a> </p> <div id="image"></div> </form> </div> <div id="result"><?= $result_message ?></div> </body> </html>
client.js この部分は、ver.2 では選択は1つだけでしたが、今回は複数選択が可能になっています( クリアのタイミングが違うだけです )。 $("#image").html(""); による画像クリアをここで実行していません。画像のクリアは、upload.js の #.ajax の正常終了時のイベントの最後で行っています。
$(function(){
// INPUT type="file" のファイル選択後のイベント
$("#target").on("change", function(){
// 選択されたファイルの情報
console.dir( this.files );
// ファイル参照用のクラス : FileReader
var reader = new FileReader();
// 表示用にプロパティを追加
reader.name = this.files[0].name;
reader.type = this.files[0].type;
// 画像が読み込まれると実行されるイベント
$(reader).on("load", function () {
// FileReader の内容
console.dir( this );
if ( this.type.indexOf("image/") == 0 ) {
$("<img>").appendTo("#image")
.prop( {"src": this.result, "title": this.name + " : " + this.type } )
.css( {"width": "160px", "margin": "10px","border": "1px solid #c0c0c0" } );
}
else {
$("<img>").appendTo("#image")
.prop( {"src": "./notimage.png", "title": this.name + " : " + this.type } )
.css( {"width": "160px", "margin": "10px","border": "1px solid #c0c0c0" } );
}
});
if (this.files[0]) {
// 画像を読み込み
reader.readAsDataURL(this.files[0]);
}
});
});
upload.js $.ajax と FormData オブジェクトの処理です。但し、アップロードするデータは type="file" を持つ INPUT 要素で作成されるファイルオブジェクトでは無く、FileReader オブジェクトで作成された base64 の文字列を持つ画像を使用します。
$(function(){
// *************************************
// アップロード処理
// *************************************
$("#frm").submit( function(event){
// 本来の送信処理はキャンセルする
event.preventDefault();
// アップロードする画像があるかどうかのチェック
if ( $("#image").html() == "" ) {
options.error("アップロードする画像ファイルを選択して下さい");
return;
}
if ( !confirm("アップロードを開始してもよろしいですか?") ) {
return;
}
// 操作不可に設定
$("#content input").prop("disabled", true);
// 結果の表示エリアを全てクリア
$("#result").html( "" );
// **************************************
// ファイルのアップロード
// **************************************
console.log("アップロード処理開始");
var formData = new FormData();
// 画像データサイズの制限
formData.append("MAX_FILE_SIZE", 10000000);
var file_cnt = 0;
$("#image img").each( function() {
var base64 = $(this).prop("src");
var bin = atob(base64.split(',')[1]);
var buffer = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) {
buffer[i] = bin.charCodeAt(i);
}
var blob = new Blob([buffer.buffer], {type: "application/octet-stream"});
file_cnt++;
var file_name = (new Date()).getTime();
formData.append("image"+file_cnt, blob, file_name +"_"+file_cnt+".dat");
});
formData.append("FILE_COUNT", file_cnt );
$.ajax({
url: "./upload.php",
type: "POST",
data: formData,
processData: false, // jQuery がデータを処理しないよう指定
contentType: false // jQuery が contentType を設定しないよう指定
})
.done(function( data, textStatus ){
console.log( "status:" + textStatus );
console.log( "data:" + JSON.stringify(data, null, " ") );
alert("アップロード処理が完了しました");
// アップロード結果の表示
$.each(data, function( idx, image ){
if ( image.error != 0 ) {
$("#result").append("<span id=\"result" +idx+"\"></span><b style='color:red'>" + image.name+ " : " + image.result +"</b><br>");
}
else {
$("#result").append("<span id=\"result" +idx+"\"></span>" + image.name + " : " + image.result + "<br>");
}
});
// 画像表示のクリア
$("#image").html("");
})
.fail(function(jqXHR, textStatus, errorThrown ){
console.log( "status:" + textStatus );
console.log( "errorThrown:" + errorThrown );
})
.always(function() {
// 操作不可を解除
$("#content input").prop("disabled", false);
})
;
});
});
upload.php
サーバ側でファイルアップロードを担当する upload.php は、返すデータは JSON フォーマットであり、MIME は application/json です。これによって、$.ajax は直接 JSON オブジェクトを返す事になります。
<?php
// キャラクタセット
// *************************************
header( "Content-Type: application/json; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();
// ファイルを移動するフォルダ
$image_path = "./myimages";
// フォルダが無ければ作成
if ( !is_dir( $image_path ) ) {
mkdir( $image_path );
}
$cnt = $_POST["FILE_COUNT"] + 0;
for( $i = 0; $i < $cnt; $i++ ) {
$image_target = "image".($i+1);
if ( $_FILES[$image_target]["error"] == 0 ) {
// *************************************
// 1) 画像フォーマットの取得
// *************************************
$type_string = image_type_to_mime_type( exif_imagetype( $_FILES[$image_target]['tmp_name'] ) );
// *************************************
// 2) オリジナルファイル名の取得
// *************************************
$file = explode(".", $_FILES[$image_target]['name']);
// *************************************
// 3) 日本語ファイル名対応
// *************************************
$file_name = urlencode( $file[0] );
// *************************************
// 4) 保存ファイル名を作成
// a) 拡張子決定
// b) uniqid() でファイル目をユニーク
// *************************************
$target = "";
if ( $type_string == "image/jpeg" ) {
$target = uniqid() . "_{$file_name}.jpg";
}
if ( $type_string == "image/gif" ) {
$target = uniqid() . "_{$file_name}.gif";
}
if ( $type_string == "image/png" ) {
$target = uniqid() . "_{$file_name}.png";
}
if ( $target == "" ) {
$_FILES["image"]["result"][] = "アップロードできないフォーマットです";
}
else {
// *************************************
// アップロードファイルの保存
// *************************************
if ( @move_uploaded_file( $_FILES[$image_target]['tmp_name'], "{$image_path}/{$target}" ) ) {
$_FILES[$image_target]["result"] = "アップロードに成功しました";
}
else {
// なんらかの環境エラー
$_FILES[$image_target]["result"] = "アップロードに失敗しました";
}
}
}
else {
switch($_FILES[$image_target]["error"]){
case 1:
$_FILES[$image_target]["result"] = "php.ini の upload_max_filesize ディレクティブの値を超えています";
break;
case 2:
$_FILES[$image_target]["result"] = "HTML フォームで指定された MAX_FILE_SIZE を超えています";
break;
case 3:
$_FILES[$image_target]["result"] = "一部のみしかアップロードされていません";
break;
case 4:
$_FILES[$image_target]["result"] = "アップロードされませんでした";
break;
case 6:
$_FILES[$image_target]["result"] = "テンポラリフォルダがありません";
break;
case 7:
$_FILES[$image_target]["result"] = "ディスクへの書き込みに失敗しました";
break;
case 8:
$_FILES[$image_target]["result"] = "PHP の拡張モジュールがファイルのアップロードを中止しました";
break;
default:
$_FILES[$image_target]["result"] = "不明なエラーです";
}
}
}
print json_encode($_FILES)
?>
|
|
【PHP + WEBアプリの最新記事】
- PHP : 選択した画像の表示 / ファイルアップロード ver.2
- PHP : ファイルアップロード ver.1
- 超簡易掲示板 ( JSON ) : PHP / CSS でスマホ用レスポンシブ対応
- PHP : 曲線が必要ならば ImageMagick ( 但し使えるかどうかはサーバー次第 )
- GD で画像縮小。『1) 単純縮小、2) 幅にあわす 3) 高さにあわす 4) 任意の幅と高さ』をその他の処理も含めてクラスでまとめ( class GD )
- PHP : 超簡易ログ
- PHP + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート
- Windows で Laravel を試す際、PHP の Windows バージョンが 5.6.30 なので、Laravel 5.2 をインストールします
- Laravel を試す為に Windows に Composer をインストール
- スマホ対応、サーバインデックス表示パッケージ( jQuery + Bootstrap(css) + mmenu + PHP )
- 超簡易掲示板 : 保存タイプは CSV
- PHP による『超簡易掲示板』 / アプリケーションからの POST 検証用
- PHP : 既存 GD 関連ライブラリで、背景をグラデーション(2)
- PHP : 既存 GD 関連ライブラリで、背景をグラデーション
- PHP : 入力値のデバッグ
- PHP : ImageMagick : 背景が透過する画像を作成
- PHP雛型(2会話DB更新処理) : MySQL、XMLHttpRequest、XML、JSON、Canvas
- PHP をテストする為の初心者用フォーム



model.php
ここは、もう使用しません( 標準化の為、model.php を削除する事はありません )
client.js
この部分は、
upload.js
$.ajax と FormData オブジェクトの処理です。但し、アップロードするデータは type="file" を持つ INPUT 要素で作成される



