date(“ymdHis”)だけだと怖いので、mt_rand(1,9)も追加します。
$rand = mt_rand(1,9);
$date = date("ymdHis");
$path = "upload/img/".$date.$rand;
mkdir($path, 0777);
echo "finish!<br>";
echo "passは" .$path. "です。";


はい、ガンガンいきましょう。
随机应变 ABCD: Always Be Coding and … : хороший
date(“ymdHis”)だけだと怖いので、mt_rand(1,9)も追加します。
$rand = mt_rand(1,9);
$date = date("ymdHis");
$path = "upload/img/".$date.$rand;
mkdir($path, 0777);
echo "finish!<br>";
echo "passは" .$path. "です。";


はい、ガンガンいきましょう。
<?php
for ($i=0; $i<count($_FILES['files']['name']) and $i < 2; $i++) {
$file_ext = pathinfo($_FILES["files"]["name"][$i], PATHINFO_EXTENSION);
if (FileExtensionGetAllowUpload($file_ext) && is_uploaded_file($_FILES["files"]["tmp_name"][$i])) {
if(move_uploaded_file($_FILES["files"]["tmp_name"][$i], "upload/img/".$_FILES["files"]["name"][$i])) {
$message .= $_FILES["files"]["name"][$i] . "を送信しました。<br>";
$message .= "fileのパスは upload/img/".$_FILES["files"]["name"][$i]." です。<br>";
} else {
$message = "ファイルをアップロードできません。<br>";
}
} else {
$message = "ファイルが選択されていません。<br>";
}
}
function FileExtensionGetAllowUpload($ext){
$allow_ext = array("gif","jpg","jpeg","png");
foreach($allow_ext as $v){
if ($v === $ext){
return 1;
}
}
return 0;
}
?>
<style>
.thumb {
height: 100px;
width: 100px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
h1 {
margin:0px;
}
#caution {
color:gray;
font-size:small;
}
</style>
<h1>添付ファイルを送信</h1>
<div id="caution">
※送信できるファイルの拡張子は"gif","jpg","jpeg","png"の何れかです。<br>
※ファイル送信は最大2つまでです。3つ以上選択しても、3つ目以降は送れません。また、二つのファイルを送信する場合は、キーボードの"ctl"ボタンなどで二つ選択した状態で開いてください。</div><br>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple />
<input type="submit" value="送信">
</form>
<?php echo $message; ?>
<output id="list"></output>
<script>
function handleFileSelect(evt){
var files = evt.target.files;
if(files.length > 2){
files = files.slice(0, 2);
}
for (var i = 0, f; f = files[i]; i++) {
// for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function(theFile){
return function(e){
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
var output = [];
for (var i = 0, f; f = files[i]; i++) {
// for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
同じファイル名を送信すると、ファイルが上書きされてしまうので、保存するディレクトリを送信ごとにユニークにする必要がありますね。

適当に数時間試していたら上手くいきました。
変数のlengthをcountして条件分岐で欲しい数だけsliceしてます。
<script>
function handleFileSelect(evt){
var files = evt.target.files;
if(files.length > 2){
files = files.slice(0, 2);
}
for (var i = 0, f; f = files[i]; i++) {
// for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function(theFile){
return function(e){
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
var output = [];
for (var i = 0, f; f = files[i]; i++) {
// for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
OK! Nice!

さて、問題は、送信ファイルをどうやって保存するかですね。
gmailやhotmailなどは、ファイル名は変わらずに送られてくるので、拡張子にバリデーションをかけて、ファイル名はそのままにしたいと思います。
for文の繰り返し処理をand $i < 2とすることで、3つ以上のファイルがpostされても、処理されるのは2つに制限できる。
for ($i = 0; $i < count($_FILES['files']['name']) and $i < 2; $i++) {
$file_ext = pathinfo($_FILES["files"]["name"][$i], PATHINFO_EXTENSION);
if (FileExtensionGetAllowUpload($file_ext) && is_uploaded_file($_FILES["files"]["tmp_name"][$i])) {
if(move_uploaded_file($_FILES["files"]["tmp_name"][$i], "upload/img/".$_FILES["files"]["name"][$i])) {
echo $_FILES["files"]["name"][$i] . "をアップロードしました。
“;
} else {
echo “ファイルをアップロードできません。
“;
}
} else {
echo “ファイルが選択されていません。
“;
}
}

問題はjavascript側なんだが、
var i = 0, f; f = files[i], i < 2; i++
と書いても、制御ができない。。。
しかも、画像とテキストで二つのfor文を回しているのだが、
二つ目のfor文が上手く動かない。困った。
[code]
function handleFileSelect(evt){
var files = evt.target.files;
for (var i = 0, f; f = files[i], i < 2; i++) {
// for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function(theFile){
return function(e){
var span = document.createElement('span');
span.innerHTML = ['‘].join(”);
document.getElementById(‘list’).insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
var output = [];
for (var i = 0, f; f = files[i]; i++) {
// for (var i = 0, f; f = files[i]; i++) {
output.push(‘
‘);
}
document.getElementById(‘list’).innerHTML = ‘
‘;
}
[/code]

コードでは一番下に来ていますが、addEventListenerで、getElementById(‘files’).addEventListener(‘change’, handleFileSelect, false)として、handleFileSelectの関数を実行します。
handleFileSelectでは、new FileReader();とした後、errorHandlerとupdateProgressを実行します。
%は、Math.round((evt.loaded / evt.total) * 100);
<style>
#progress_bar {
margin: 10px 0;
padding: 3px;
border: 1px solid #000;
font-size: 14px;
clear: both;
opacity: 0;
-moz-transition: opacity ls linear;
-o-transition: opacity ls linear;
-webkit-transition: opacity ls linear;
}
#progress_bar.loading {
opacity: 1.0;
}
#progress_bar .percent {
background-color: #99ccff;
height: auto;
width: 0;
}
</style>
<input type="file" id="files" name="file" />
<button onclick="abortRead();">Cancel read</button>
<div id="progress_bar"><div class="percent">0%</div></div>
<script>
var reader;
var progress = document.querySelector('.percent');
function abortRead(){
reader.abort();
}
function errorHandler(evt){
switch(evt.target.error.code){
case evt.target.error.NOT_FOUND_ERR:
alert('File Not Found!');
break;
case evt.target.error.NOT_READABLE_ERR:
alert('File is not readable');
break;
case evt.target.error.ABORT_ERR:
break;
default:
alert('An error occurred reading this file.');
};
}
function updateProgress(evt) {
if (evt.lengthComputable) {
var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
if (percentLoaded < 100) {
progress.style.width = percentLoaded + '%';
progress.textContent = percentLoaded + '%';
}
}
}
function handleFileSelect(evt) {
progress.style.width = '0%';
progress.textContent = '0%';
reader = new FileReader();
reader.onerror = errorHandler;
reader.onprogress = updateProgress;
reader.onabort = function(e) {
alert('File read cancelled');
};
reader.onloadstart = function(e) {
document.getElementById('progress_bar').className = 'loading';
};
reader.onload = function(e) {
progress.style.width = '100%';
progress.textContent = '100%';
setTimeout("document.getElementById('progress_bar').className='';", 2000);
}
reader.readAsBinaryString(evt.target.files[0]);
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
容量が小さいと、直ぐに100%となるので、最近downloadして重かったJavaの”spring-tool-suite-3.9.2.RELEASE-e4.7.2-win32-x86_64.zip”で試してみます。
いや、参りました。って感じですかね。参ってばっかりですが。。

FileReader クラスは、HTML5 世代の機能
File APIで出来ること
-ローカルにある画像をアップロードする前にプレビューを表示する
-ローカルにある画像をブラウザで加工してダウンロードする
-テキストファイルをブラウザで解析する
-データをJSONファイルとしてエクスポートして、インポートする
-大きなファイルを分割してサーバーに送信する
特に、「ローカルにある画像をアップロードする前にプレビューを表示する」ですね。
readAsDataURL メソッドは、指定された Blob ないし File オブジェクトを読み込むために使用
reader.readAsDataURL(file);
escape():16 進数エスケープシーケンスに置換
insertBefore:指定のノードを現在のノードの子ノードとして参照要素の前に挿入
<style>
.thumb {
height: 100px;
width: 100px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
</style>
<input type="file" id="files" name="files[]" multiple /><br>
<output id="list"></output>
<script>
function handleFileSelect(evt){
var files = evt.target.files;
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function(theFile){
return function(e){
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
初期

画像を選択

選択後
なんだこりゃーー!!すげー

では繋げてみましょう。
<?php
for ($i=0; $i<count($_FILES['files']['name']); $i++) {
$file_ext = pathinfo($_FILES["files"]["name"][$i], PATHINFO_EXTENSION);
if (/*FileExtensionGetAllowUpload($file_ext) && */ is_uploaded_file($_FILES["files"]["tmp_name"][$i])) {
if(move_uploaded_file($_FILES["files"]["tmp_name"][$i], "upload/img/".$_FILES["files"]["name"][$i])) {
echo $_FILES["files"]["name"][$i] . "をアップロードしました。<br>";
} else {
echo "ファイルをアップロードできません。<br>";
}
} else {
echo "ファイルが選択されていません。<br>";
}
}
//アップロードできるファイルに拡張子の制限をかけたい時
function FileExtensionGetAllowUpload($ext){
$allow_ext = array("gif","jpg","jpeg","png","eps");
foreach($allow_ext as $v){
if ($v === $ext){
return 1;
}
}
return 0;
}
?>
<style>
.thumb {
height: 100px;
width: 100px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
</style>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple />
<input type="submit" value="Send">
</form>
<output id="list"></output>
<script>
function handleFileSelect(evt){
var files = evt.target.files;
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
var reader = new FileReader();
reader.onload = (function(theFile){
return function(e){
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
ほお

php側にもちゃんと渡されています。
<style>
#drop_zone {
height:100px;
width:400px;
background-color:#EEEEEE;
display: flex;
align-items: center;
justify-content: center;
color:white;
}
</style>
Drop files here
<div id="drop_zone">ここに添付ファイルをドロップ</div>
<output id="list"></output>
<script>
function handleFileSelect(evt){
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files;
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
function handleDragOver(evt){
evt.stopPropagation();
evt.preventDefault();
evt.dataTransfer.dropEffect = 'copy';
}
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
</script>
あ、これマジ凄い

preventDefault() は、その要素のイベントをキャンセルし、stopPropagation()は、親要素への伝播をキャンセル
dataTransfer:ドラッグを開始した時に、DataTransfer オブジェクトを取得する
addEventListener(‘dragover’,”,false)ドロップ領域に入っている間連続して発生
addEventListener(‘drop’,”,false)ドロップされた時に発生
var file = event.target.files[0]; で、ファイルオブジェクトを取り出す。
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
<script>
function handleFileSelect(evt){
var files = evt.target.files;
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

jsで複数の初期化式
<script>
document.write("<p>");
for(var i = 1, j=10; i < 10; i++, j++){
document.write("i = " + i + ", j = " + j + "<br>");
}
document.write("</p>");
</script>

toLocaleDateString()
->日付のみ抽出
<script> var date = new Date(); document.write(date.toLocaleDateString()); </script>

addEventListener
イベント追加
<form>
<input type="button" id="ev" value="button" onclick="func1()">
</form>
<script>
function func1(){ alert("関数1が呼び出されました");}
var obj = document.getElementById("ev");
obj.addEventListener("click", func2, false);
function func2(){ alert("関数2が呼び出されました");}
obj.addEventListener("click", function(){
alert("関数3が呼び出されました")
}, false);
</script>

つなげると、
<?php
for ($i=0; $i<count($_FILES['files']['name']); $i++) {
$file_ext = pathinfo($_FILES["files"]["name"][$i], PATHINFO_EXTENSION);
if (/*FileExtensionGetAllowUpload($file_ext) && */ is_uploaded_file($_FILES["files"]["tmp_name"][$i])) {
if(move_uploaded_file($_FILES["files"]["tmp_name"][$i], "upload/img/".$_FILES["files"]["name"][$i])) {
echo $_FILES["files"]["name"][$i] . "をアップロードしました。<br>";
} else {
echo "ファイルをアップロードできません。<br>";
}
} else {
echo "ファイルが選択されていません。<br>";
}
}
//アップロードできるファイルに拡張子の制限をかけたい時
function FileExtensionGetAllowUpload($ext){
$allow_ext = array("gif","jpg","jpeg","png","eps");
foreach($allow_ext as $v){
if ($v === $ext){
return 1;
}
}
return 0;
}
?>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files[]" multiple />
<input type="submit" value="Send">
</form>
<output id="list"></output>
<script>
function handleFileSelect(evt){
var files = evt.target.files;
var output = [];
for (var i = 0, f; f = files[i]; i++) {
output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
f.size, ' bytes, last modified: ',
f.lastModifiedDate.toLocaleDateString(), '</li>');
}
document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>
いいですね!
onChangeとは、フォーム内のエレメント(要素)の内容が変更された時に起こるイベント処理
sample
<form name="link">
<select name="linkselect" onChange="confirm()">
<option value="">選択してください</option>
<option value="https://products.office.com/ja-jp/exchange/exchange-online">Microsoft Exchange Online</option>
<option value="https://willcloud.jp/">Will Mail</option>
<option value="http://www.cybersaas.jp/">CYBERMAIL Σ</option>
</select>
</form>
<script>
function confirm(){
obj = document.link.linkselect;
index = obj.selectedIndex;
if(index != 0){
href = obj.options[index].value;
location.href = href;
}
}
</script>
