phpでメールボックスをつくろう7 送信したメールを表示

getパラメーターでメールのidを取得して、テーブルから呼び出します。

<?php elseif($_GET&#91;"path"&#93; == 'mailrp'): ?>
			<?php
			$id = empty($_GET&#91;"inbox"&#93;)? 'null' : $_GET&#91;"inbox"&#93;;

			$dsn = "mysql:dbname=mail;host=localhost";
			$user = "hoge";
			$password = "hogehoge";
			try {
			    $dbh = new PDO($dsn, $user, $password);
			} catch (PDOException $e){
			    print('connection failed:'.$e->getMessage());
			}
			$sql3 = "select * from sends where id = '".$id."'";
			$stmt3 = $dbh->query($sql3);

			$result3 = $stmt3->fetch(PDO::FETCH_ASSOC);
			$send_des = $result3['destination'];
			$send_sub = $result3['subject'];
			$send_body = $result3['body'];
			$sendtime = $result3['sendtime'];

			echo "<h3>".$send_sub."</h3>";
			echo "To: ".$send_des. "<br>";
			echo $sendtime. "<hr>";
			echo $send_body. "<br>";
			?>
   <?php endif; ?>

1.nakayamaさんにメールを書く

2.送信する

3.送信一覧

4.メール詳細を表示

送信一覧は、order byでソート順逆ですね。

$sql2 = "select * from sends where username = '".$username."' order by sendtime desc";

新着順にしました。

添付ファイルの表示設計は面倒なので後にして、受信ボックスを先に作りたいと思います。

受信ボックス

受信メール

phpでメールボックスをつくろう6 送信メールの宛先・タイトルを表示

テーブルからデータを引っ張てきます。

<?php elseif($_GET&#91;"path"&#93; == 'sentitems'): ?>
   			<h2>Sent Items</h2>
   			<?php 
   			$dsn = "mysql:dbname=mail;host=localhost";
			$user = "hoge";
			$password = "hogehoge";
			$username = $_SESSION&#91;"username"&#93;;
			try {
			    $dbh2 = new PDO($dsn, $user, $password);
			} catch (PDOException $e){
			    print('connection failed:'.$e->getMessage());
			}
   			$sql2 = "select * from sends where username = '".$username."'";
			$stmt2 = $dbh2->query($sql2);

			while($result = $stmt2->fetch(PDO::FETCH_ASSOC)){
				$id[] = $result['id'];
				$destination[] = $result['destination'];
				$subject[] = $result['subject'];
				$sendtime[] = $result['sendtime'];
			}
			$i= 0;
			echo "<table>";
			foreach($destination as $value){
				echo "<tr><td> <img src=\"icon.png\"> <a href=\"\">".$value ."</a></td><td><a href=\"\">". $subject[$i]."</a> </td><td>" .$sendtime[$i]. " </td></tr>";
				$i++;
			}
			echo "</table>";
			?>
   <?php endif; ?>

アイコンをつけてそれっぽくします。

idで、メール詳細に移動するようにします。

あああ、なるほど、gmailはメール詳細に飛ぶ際に、乱数字16桁のid使ってますね。
なるほどな~!

メールボックスをつくろう4 複数添付ファイルの機能を実装する

html側

<div class="flex-2">
   <?php if($_GET&#91;"compose"&#93; == 'new'): ?>
		<form action="?compose=done" method="post" enctype="multipart/form-data">
			宛先
			<span id="fs-s">※必須</span><br>
			<input type="text" name="to" size="90%" required><br>
			件名<br>
			<input type="text" name="subject" size="90%"><br>
			本文
			<span id="fs-s">※必須</span><br>
			<textarea name="body" rows="12" cols="100%" required></textarea>
			</p>
			<input type="file" id="files" name="files&#91;&#93;" multiple />
			<div id="caution">
			※送信できるファイルの拡張子は"gif","jpg","jpeg","png"の何れかです。<br>
			※ファイル送信は最大2つまでです。3つ以上選択しても、3つ目以降は送れません。また、二つのファイルを送信する場合は、キーボードの"ctl"ボタンなどで二つ選択した状態で開いてください。</div>
			<output id="list"></output>
			<p>
			<input type="submit" value="送信">
			</form>
   <?php elseif($_GET&#91;"compose"&#93; == 'done'): ?>
   			<p>メール送信が完了しました</p>
   <?php endif; ?>
</div>

ここまではOK

$_FILEがpostされたらフォルダを作って格納する

    if(!empty($_FILES['files']['name'])){
      $rand = mt_rand(1,9);
      $date = date("ymdHis");
      $path = "upload/img/".$date.$rand;
      mkdir($path, 0777);
    }

	  for ($i=0; $i<count($_FILES&#91;'files'&#93;&#91;'name'&#93;) and $i < 2; $i++) {
    $file_ext = pathinfo($_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;, PATHINFO_EXTENSION);
    if (FileExtensionGetAllowUpload($file_ext) &&  is_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;)) {
      if(move_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;, $path."/".$_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;)) {
          $message .= $_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93; . "を送信しました。<br>";
          $message .= "fileのパスは ".$path."/".$_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;
  }

画像選択状態

送信後のブラウザ

送信後のディレクトリ

o oh, very nice!
file1、file2のパスも以下の様に取得できますね。

if($i == 0){
            $file1 = $path."/".$_FILES["files"]["name"][$i];
            $message .= "file1のパスは ".$file1." です。<br>";
          } else {
            $file2 = $path."/".$_FILES["files"]["name"][$i];
            $message .= "file2のパスは ".$file2." です。<br>";
          }

date(“ymdHis”);のフォルダをつくる

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&#91;'files'&#93;&#91;'name'&#93;) and $i < 2; $i++) {
    $file_ext = pathinfo($_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;, PATHINFO_EXTENSION);
    if (FileExtensionGetAllowUpload($file_ext) &&  is_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;)) {
      if(move_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;, "upload/img/".$_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;)) {
          $message .= $_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93; . "を送信しました。<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&#91;&#93;" 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>

同じファイル名を送信すると、ファイルが上書きされてしまうので、保存するディレクトリを送信ごとにユニークにする必要がありますね。

php側のファイルのアップロードの数に制限をかける

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(‘

  • ‘, escape(f.name), ‘(‘, f.type || ‘n/a’, ‘) -‘,
    f1.size, ‘ bytes, last modified: ‘,
    f1.lastModifiedDate.toLocaleDateString(), ‘
  • ‘);
    }
    document.getElementById(‘list’).innerHTML = ‘

      ‘ + output.join(”) + ‘

    ‘;
    }
    [/code]

    ファイルをアップロード

    ファイルのmax sizeを指定します。

    <form method="post" action="#" enctype="multipart/form-data">
    		ファイル:<input type="file" name="up_file"><br>
    		<input type="submit" value="upload">
    		<input type="hidden" name="MAX_FILE_SIZE" value="4194304" />
    </form>
    

    fileが一時保存の領域に保存されているか確認

    <?php
    	if(is_uploaded_file($_FILES&#91;'up_file'&#93;&#91;'tmp_name'&#93;)){
    		if(move_uploaded_file($_FILES&#91;'up_file'&#93;&#91;'tmp_name'&#93;,"./".$_FILES&#91;'up_file'&#93;&#91;'name'&#93;)){
    			echo "uploaded";
    		} else {
    			echo "error while saving.";
    		}
    	} else {
    		echo "file not uploaded.";
    	}
    
    ?>
    <form method="post" action="#" enctype="multipart/form-data">
    		ファイル:<input type="file" name="up_file"><br>
    		<input type="submit" value="upload">
    		<input type="hidden" name="MAX_FILE_SIZE" value="4194304" />
    </form>
    

    保存場所を/upload/img/test.gif と指定します。

    if(is_uploaded_file($_FILES['up_file']['tmp_name'])){
    		if(move_uploaded_file($_FILES['up_file']['tmp_name'],"./upload/img/test.gif")){
    			echo "uploaded";
    		} else {
    			echo "error while saving.";
    		}
    	} else {
    		echo "file not uploaded.";
    	}
    

    保存されています。

    phpでメールボックスをつくろう3 DBと接続

    メール送信後のテーブルを作成します。file送信の機能は後から追加の予定。

    create table mail.sends(
    	id int unsigned auto_increment primary key,
    	username varchar(41),
    	destination varchar(41),
    	subject varchar(255),
    	body varchar(255),
    	file1 varchar(255),
    	file2 varchar(255),
    	sendtime datetime default null
    );
    

    DBへの接続 ”to”がpostされたら、DBに入れます。

    session_start();
    if(isset($_POST["to"])){
    	$username = $_SESSION["username"];
    	$destination = htmlspecialchars($_POST["to"]);
    	$subject = htmlspecialchars($_POST["subject"]);
    	$body = htmlspecialchars($_POST["body"]);
    	$date =	date("Y-m-d h:i");
    
    	$dsn = "mysql:dbname=mail;host=localhost";
    	$user = "hoge";
    	$password = "hogehoge";
    	 
    	try {
    	    $dbh = new PDO($dsn, $user, $password);
    	} catch (PDOException $e){
    	    print('connection failed:'.$e->getMessage());
    	}
    
    	$stmt = $dbh -> prepare("INSERT INTO sends (username, destination, subject, body, sendtime) VALUES(:username, :destination, :subject, :body, :sendtime)");
        $stmt->bindParam(':username', $username, PDO::PARAM_STR);
        $stmt->bindParam(':destination', $destination, PDO::PARAM_STR);
        $stmt->bindParam(':subject', $subject, PDO::PARAM_STR);
        $stmt->bindParam(':body', $body, PDO::PARAM_STR);
        $stmt->bindParam(':sendtime', $date, PDO::PARAM_STR);
        $stmt->execute();
    }
    

    メールを新規作成します。

    ブラウザ上の挙動

    mysql側
    select * from sends

    mysql> select * from sends;
    +----+----------+-------------+----------------------------------------------------------+--------------------------------------------------------------------------------------------+-------+-------+---------------------+
    | id | username | destination | subject                                                  | body                                                                                       | file1 | file2 | sendtime            |
    +----+----------+-------------+----------------------------------------------------------+--------------------------------------------------------------------------------------------+-------+-------+---------------------+
    |  1 | sample   | tanaka      | 2,000円分の割引クーポンが発行されました                  | 対象ショップ
    -31 Sons de mode
    -CANAL JEAN
    -ORiental TRaffic
    -GRACE CONTINENTAL
           | NULL  | NULL  | 2018-03-26 10:23:00 |
    +----+----------+-------------+----------------------------------------------------------+--------------------------------------------------------------------------------------------+-------+-------+---------------------+
    1 row in set (0.00 sec)
    

    入ってますね。
    時間は $date = date(“Y-m-d h:i”); ではなく、$date = date(“Y-m-d H:i”); ですね。

    次は、
    1.添付ファイルを送りたい。
    2.メールの宛先がusernamesの中になければ、宛先なしで送信エラーとしたい。
    3.send itemをクリックすると、sendテーブルから送信メールを呼び出したい。

    あれ、まてよ、
    受け取るtestは、receiveテーブルから読み込む想定なので、receiveテーブルにもinsertしないといけない?

    phpでメールボックスをつくろう2 新規作成

    <div class="flex-2">
       <?php if($_GET&#91;"compose"&#93; == 'new'): ?>
    		<form action="" method="post">
    			宛先:<br>
    			<span id="fs-s">※送り先のユーザ名を入力してください</span>
    			<input type="text" name="to" size="90%"><br>
    			件名:<br>
    			<input type="text" name="subject" size="90%"><br>
    			本文:<br>
    			<textarea name="body" rows="12" cols="100%"></textarea>
    			</p>
    			<p>
    			<input type="submit" value="送信">
    			</form>
       <?php endif; ?>
    </div>
    

    宛先と本文を必須(required)にする

    <?php if($_GET&#91;"compose"&#93; == 'new'): ?>
    		<form action="" method="post">
    			宛先
    			<span id="fs-s">※必須</span><br>
    			<input type="text" name="to" size="90%" required><br>
    			件名<br>
    			<input type="text" name="subject" size="90%"><br>
    			本文
    			<span id="fs-s">※必須</span><br>
    			<textarea name="body" rows="12" cols="100%" required></textarea>
    			</p>
    			<p>
    			<input type="submit" value="送信">
    			</form>
       <?php endif; ?>
    

    DBに入れるため、postの内容を受け取り、変数に格納する

    session_start();
    if(isset($_POST["to"])){
    	$to = $_POST["to"];
    	$subject = $_POST["subject"];
    	$body = $_POST["body"];
    }
    

    送信後はパラメータを”?compose=done”に変更する

    <?php if($_GET&#91;"compose"&#93; == 'new'): ?>
    		<form action="?compose=done" method="post">
    			宛先
    			<span id="fs-s">※必須</span><br>
    			<input type="text" name="to" size="90%" required><br>
    			件名<br>
    			<input type="text" name="subject" size="90%"><br>
    			本文
    			<span id="fs-s">※必須</span><br>
    			<textarea name="body" rows="12" cols="100%" required></textarea>
    			</p>
    			<p>
    			<input type="submit" value="送信">
    			</form>
       <?php elseif($_GET&#91;"compose"&#93; == 'done'): ?>
       			<p>メール送信が完了しました</p>
       <?php endif; ?>
    

    おお、なんか凄い疲れた。