トップページ

このサイトについて

ゲーム

イラスト

プログラミング

動画

音楽

雑記

ブログ

JavascriptとPHPでアップローダを作る
画像ファイルなどを投稿するためのアップローダの作り方を紹介します。

これができたアップローダの例で、ドラッグ&ドロップで画像をアップロードすることができます。
ここにファイルをドロップ


の3つを組み合わせて使います。
参考にさせていただいたサイトは
Javascriptの部分: http://qiita.com/tsunet111/items/0167704a65ebc04411f9
HTML5の部分: http://wataame.sumomo.ne.jp/archives/3879
です。

まずドロップ用のボックスをhtmlで作ります。
以下はサンプルコードです。
	<!DOCTYPE HTML>
	<html lang="ja">
	  <head>
	    <style type="text/css"><!--
	      #dropzone {
	        background-color: #ddd; min-height: 160px;
	      }
	      #dropzone.dropover {
	        background-color: #ddd; color: #aaa;
	      }
	      #files:empty::before { color: #ccc; }
	      #files img {
	        max-height: 128px; max-width: 128px;
	      }
	    //--></style>
	    <meta charset="UTF-8">
	    <title>ファイルのアップロードのサンプル</title>
	  </head>
	  <body>

	    <h3>ファイルのアップロードのサンプル</h3>

	    <div id="dropzone" effectAllowed="move">ここにファイルをドロップ</div>
	  	<ul id="files"></ul>
	    <script src="./jquery-3.1.1.min.js"></script>
	  	<script src="dropfile.js"></script>

	  </body>
	</html>

<div id="dropzone" effectAllowed="move">ここにファイルをドロップ</div>
という箇所がドロップ時の操作を定義したdropfile.jsと連絡してファイルを送信します。

次にjavascriptファイル dropfile.jsにファイルを送信する機能を書きます。
ここではファイルの送受信のためにjQueryというライブラリを使っています。
http://jquery.com/download/からダウンロードできます。
使うときはダウンロードできるjquery-3.3.1.min.jsかjquery-3.3.1.jsというファイルを
upload.htmlと同じ階層に置けばOKです。
	function postJump(files){
	  //ファイルをupload.phpに送信
	  var formdata = new FormData();
	  $.each(files, function(i, file){
			formdata.append('upfile' + i, file);
		});
	  // 送信
	  $.ajax({
	  	type: 'POST',
	  	url : './upload.php',
	  	data: formdata,
	  	processData: false,	// jQueryがデータを処理しないように設定
	  	contentType: false,	// jQueryがcontentTypeを設定しないように設定
	  }).done(function(responseData, status, jqXHR)
	  {
	      console.log(responseData);
	  }).fail(function(responseError, status, errorThrown)
	  {
	      console.log(responseError);
	  });
	}

	(function() {
		var elDrop = document.getElementById('dropzone');
		var elFiles = document.getElementById('files');

		elDrop.addEventListener('dragover', function(event) {
				event.preventDefault();
				event.dataTransfer.dropEffect = 'copy';
		});

		elDrop.addEventListener('drop', function(event) {
				//ドロップ時にファイルをアップロード
				event.preventDefault();
				var files = event.dataTransfer.files;
				showFiles(files);
				postJump(files);
		});

		document.addEventListener('click', function(event) {
			var elTarget = event.target;
			if (elTarget.tagName === 'IMG') {
				var src = elTarget.src;
	      //クリックしたら別ウィンドウで画像を開く
				var w = window.open('about:blank');
				var d = w.document;
				d.open();
				d.write('<img src="' + src + '" />');
				d.close();
			}
		});

		function showFiles(files) {
	    //アップロードされたファイルの情報を表示
			for (var i=0, l=files.length; i<l; i++) {
					var file = files[i];
					var elFile = buildElFile(file);
					elFiles.appendChild(elFile);
			}
		}

		function buildElFile(file) {
				var elFile = document.createElement('li');
				var text = file.name + ' (' + file.type + ',' + file.size + 'bytes)';
				elFile.appendChild(document.createTextNode(text));
				if (file.type.indexOf('image/') === 0) {
					var elImage = document.createElement('img');
					elImage.src = "";
					elFile.appendChild(elImage);
					attachImage(file, elImage);
				}
				return elFile;
		}

		function attachImage(file, elImage) {
			var reader = new FileReader();
			reader.onload = function(event) {
				var src = event.target.result;
				elImage.src = src;
				elImage.setAttribute('title', file.name);
			};
			reader.readAsDataURL(file);
		}
	})();
この中で大事な部分はまず32行目の
elDrop.addEventListener('drop', function(event) { ... }
の部分で、ここでボックスにドロップされた時の動作(エベントリスナ)を定義しています。
実際にファイルをアップロードするのはpostJump関数で、これがファイルをまとめたのちに
ファイルを保存してくれるupload.phpへPOSTリクエストで送信しています。


最後にdropfile.jsのPOSTリクエストを受け取るupload.phpを用意します。
これは$_FILESの要素を一つずつ保存するもので、必要なエラーチェックなどもします。
<?php
//参考 http://wataame.sumomo.ne.jp/archives/3879
header("Content-Type: text/html; charset=UTF-8");
define('FILE_PATH','./images/'); //保存するパスを指定

if ( !empty($_FILES) ) {
  for ( $i=0; $i<count($_FILES); $i++ ) {
		echo $_FILES;
		$upfile_i = 'upfile' . $i; //i個目のファイル
		if ( is_uploaded_file($_FILES[$upfile_i]['tmp_name']) ) {
			$name = $_FILES[$upfile_i]['name'];
			$tempFile = $_FILES[$upfile_i]['tmp_name'];
			print_r($_FILES[$upfile_i]);

			// Validate the file type
			$fileTypes = array('jpg','jpeg','gif','png');   // File extensions
			$fileParts = pathinfo($_FILES[$upfile_i]['name']);

			// ファイル名がアルファベットのみかをチェック
			if ( preg_match("/^([a-zA-Z0-9\.\-\_])+$/ui", $name) == "0" ) {
			    // アルファベット以外を含む場合はファイル名を日時とする
			    $saveFileName = date("Ymd_His", time());
			}
			else {
			  echo "ファイル: $name\n";
			  if ( preg_match("/\.jpg$/ui", $name) == true ) {
			      $ret = explode('.jpg', $name);
			  }
				elseif ( preg_match("/\.gif$/ui", $name) == true ) {
			      $ret = explode('.gif', $name);
			  }
				elseif ( preg_match("/\.png$/ui", $name) == true ) {
			      $ret = explode('.png', $name);
			  }
			  $saveFileName = $ret[0]; // 拡張子を除いたそのまま
			}

			// マイクロ秒をファイル名に付加
			$saveFileName = FILE_PATH . '[' . (microtime()*1000000) . ']' . $saveFileName;
			if ( in_array($fileParts['extension'], $fileTypes) )
			{
				if ( move_uploaded_file($_FILES[$upfile_i]["tmp_name"],
					$saveFileName . '.' . $fileParts['extension']) )
				{
					//chmod($saveFileName . '.' . $fileParts['extension'], 0777);
					echo $_FILES[$upfile_i]["name"] . "をアップロードしました。\n";
				}
				else {
					echo "アップロードエラー";
				}
			}
			else {
			  echo "アップロードの対象は画像ファイル(.jpg/.gif/.png)のみです。<br>\n";
			  $filename = $_FILES[$upfile_i]['name'];
			  echo "ファイル: $filename";
			}
		}
		else {
			echo "アップロードエラー: ファイルがアップロードされていません。\n";
		}
	}
}
else {
  echo "アップロードエラー: FILESが空です。";
}
?>

以上の3ファイルを置いたディレクトリにさらにimages/というサブディレクトリをつくっておけば、
そこに画像ファイルが保存されていきます。