login.php
<?php
session_start();
$_SESSION=[];//セッションデータを破棄
setcookie(session_name(),"",time()-360);//クライアントのクッキー削除
session_destroy();//サーバー側のクッキー削除
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>システムログイン</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="container">
<h1>認証</h1>
<form method="post" action="auth.php">
<table>
<tr>
<th><label for="id">ID</label></th>
<td><input type="text" name="id" id="id"></td>
</tr>
<tr>
<th><label for="password">パスワード</label></th>
<td><input type="password" name="password" id="password"></td>
</table>
<p><button type="submit">認証</button></p>
</form>
</div>
<script src="js/script.js"></script>
</body>
</html>
auth.php
<?php
session_start();
if(empty($_POST["id"]) || empty($_POST["password"])){
header("Location: login.php");
exit();
}
require_once("config.php");
$sql="SELECT * FROM members WHERE id=:id";
$stmt=$pdo->prepare($sql);
$stmt->bindValue(":id",$_POST["id"],PDO::PARAM_INT);
$stmt->execute();
//取り出しただけなのでfetchする
$row=$stmt->fetch(PDO::FETCH_ASSOC);
//ハッシュ済みと送られてきたpassの比較
if(password_verify($_POST["password"],$row["password"])){
//認証成功
session_regenerate_id();//session_idをまず最初にふりかえる
$_SESSION["login"]=true;
$_SESSION["m_name"]=$row["m_name"];
$_SESSION["id"]=$row["id"];
header("Location: mypage.php");
exit();
}else{
//認証失敗
$_SESSION=[];//全消し
header("Location: login.php");
exit();
}
?>
mypage.php
<?php
session_start();
if(empty($_SESSION["login"])){
header("Location: login.php");
exit();
}
require_once("config.php");
$sql = "SELECT mails.id AS i,subject,sendtime,m_name FROM mails,members WHERE m_from=members.id AND m_to=:m_to ORDER BY sendtime DESC";
$stmt=$pdo->prepare($sql);
$stmt->bindValue("m_to",$_SESSION["id"],PDO::PARAM_INT);
$stmt->execute();
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>マイページ</title>
<link rel="stylesheet" href="css/style.css">
<script src="../jquery-3.4.1.min.js"></script>
</head>
<body>
<div id="container">
<h1><?php echo htmlspecialchars($_SESSION["m_name"],ENT_QUOTES); ?>の受信トレイ</h1>
<div>
<a href="mailform.php">新規メール作成</a> | <a href="login.php">logout</a>
</div>
<!--メール概要を表示-->
<div id="m_list">
<table>
<tr>
<th>件名</th><th>送信者名</th><th>送信日時</th>
</tr>
<?php while($row=$stmt->fetch(PDO::FETCH_ASSOC)): ?>
<tr>
<td data-id="<?php echo $row["i"]; ?>" class="subject"><?php echo htmlspecialchars($row["subject"],ENT_QUOTES); ?></td>
<td><?php echo htmlspecialchars($row["m_name"],ENT_QUOTES); ?></td>
<td><?php echo $row["sendtime"]; ?></td>
</tr>
<?php endwhile; ?>
</table>
</div>
<hr>
<!--メール詳細を表示-->
<div id="mail">
<table>
<tr>
<th rowspan="3">詳細</th>
<td colspan="2" id="subject"></td>
</tr>
<tr>
<td id="m_name"></td><td id="sendtime"></td>
</tr>
<tr>
<td colspan="2" id="content"></th>
</tr>
</table>
</div>
</div>
<script src="js/mail.js"></script>
</body>
</html>
mailform.php
<?php
session_start();
if(empty($_SESSION["login"])) {
header("Location: login.php");
exit();
}
require_once("config.php");
$sql = "SELECT id,m_name FROM members";
$res = $pdo->query($sql);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>メール新規作成</title>
<link rel="stylesheet" href="css/style.css">
<script src="../jquery-3.4.1.min.js"></script>
</head>
<body>
<div id="container">
<h1>メール新規作成</h1>
<form action="sendmail.php" method="post">
<table>
<tr>
<th><label for="m_to">宛先</th>
<td>
<select name="m_to" id="m_to">
<option value="">選択してください</option>
<?php while($row = $res->fetch(PDO::FETCH_ASSOC)): ?>
<option value="<?php echo $row["id"]; ?>">
<?php echo htmlspecialchars($row["m_name"],ENT_QUOTES); ?>
</option>
<?php endwhile; ?>
</select>
</td>
</tr>
<tr>
<th><label for="subject">件名</label></th>
<td><input type="text" id="subject" name="subject"></td>
</tr>
<tr>
<th><label for="content">本文</label></th>
<td><textarea name="content" id="content"></textarea></td>
</tr>
</table>
<p><button type="submit">送信</button></p>
</form>
</div>
<script src="js/mail.js"></script>
</body>
</html>
sendmail.php
<?php
session_start();
if(empty($_SESSION["login"])){
header("Location: login.php");
exit();
}
if(empty($_POST["m_to"]) || empty($_POST["subject"]) || empty($_POST["content"])){
header("Location:mailform.php");
exit();
}
require_once("config.php");
$sql="INSERT INTO mails(subject,m_to,m_from,content)";
$sql .=" VALUES(:subject,:m_to,:m_from,:content)";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":subject", $_POST["subject"], PDO::PARAM_STR);
$stmt->bindValue(":m_to",$_POST["m_to"],PDO::PARAM_INT);
$stmt->bindValue(":m_from",$_SESSION["id"],PDO::PARAM_INT);
$stmt->bindValue(":content",$_POST["content"],PDO::PARAM_STR);
$stmt->execute();
header("Location: mypage.php");
?>
config.php
<?php
//-----------------------------------
//db接続情報(環境によって書き換える)
//-----------------------------------
$user="root";
$dbpass="";
$host="localhost";
$dbname="intra_mail";
//-----------------------------------
$dsn="mysql:host={$host};dbname={$dbname};charset=utf8";
$pdo=new PDO($dsn,$user,$dbpass);
?>
css/style.php
body{
background:#fee;
}
#container{
border:1px #ccc solid;
border-radius:2rem;
background:#fff;
padding:1rem;
margin:0 auto;
width:80%;
}
table {
border-collapse: collapse;
}
td, th {
border: solid 1px #000;
padding: 0.2rem 0.5rem;
text-align: left;
}
th {
background: #ccc;
}
#menu {
text-align: right;
padding: 0.5rem 0;
}
/* mail list view and mail*/
.subject {
cursor: pointer;
font-weight: bold;
text-decoration: underline;
color:#368dff;
}
#m_list {
height: 250px;
overflow: hidden scroll;
}
#m_list table, #mail table {
width: 100%;
}
#mail {
display: none;
}
#mail table th {
width: 1.5rem;
}
textarea{
width:25rem;
height:6rem;
}
hr{
margin: 1rem 0 1rem 0;
}
js/mail.js
$(function(){
//console.log("hoge");
$('td.subject').on('click', function(){
var obj = $(this).data();
//console.log(obj.id);
$(this).css({'font-weight':'normal'});
$(this).css({'text-decoration':'none'});
//件名をクリックすると詳細が出現
$('#mail').css({'display':'block'});
//Ajax通信
$.ajax({
url:'api/get_mail_data.php',
type:'get',
data:{'i':obj.id},
dataType:'json',
})
.done(function(d){
//console.log(d);
$('#subject').text("件名:"+d.subject);
$('#m_name').text("送信者:"+d.m_name);
$('#sendtime').text("送信日時:"+d.sendtime);
$('#content').html(d.content);
})
.fail(function(){
alert('NG');
});
});
});
api/get_mail_data.php
<?php
session_start();
if(empty($_GET["i"]) || empty($_SESSION["login"])){
exit();//なにもしません
}
require_once("../config.php");//一つ上のディレクトリの
$sql = "SELECT subject,m_name,sendtime,content FROM mails,members WHERE mails.id=:id AND m_from=members.id AND m_to=:m_to";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(":id",$_GET["i"],PDO::PARAM_INT);
$stmt->bindValue(":m_to",$_SESSION["id"],PDO::PARAM_INT);
$stmt->execute();
//連想配列として取り出す
$row = $stmt->fetch(PDO::FETCH_ASSOC);//1件だけのはずなので
$row["content"] = nl2br(htmlspecialchars($row["content"],ENT_QUOTES));
echo json_encode($row);
?>
tools/make_members.php
<?php
$members = [
"どらえもん"=>"doradora",
"のび太" =>"nobinobi",
"静香" =>"sizusizu",
"ジャイアン"=>"jaijai",
"スネ夫" =>"sunesune"
];
//print_r ($members);
require_once("config.php");
$sql="INSERT INTO members(m_name,password) VALUES(:m_name,:password)";//プレースホルダ
$stmt=$pdo->prepare($sql);
foreach($members as $key=>$val){
$v = password_hash($val,PASSWORD_DEFAULT);//passwordをハッシュ
//echo "<p>{$v}</p>";
$stmt->bindValue(":m_name",$key,PDO::PARAM_STR);//キーの方をバインド
$stmt->bindValue(":password",$v,PDO::PARAM_STR);//hashしたpassをバインド
$stmt->execute();
}
?>
intra_mail.sql
-- phpMyAdmin SQL Dump
-- version 4.9.2
-- https://www.phpmyadmin.net/
--
-- ホスト: 127.0.0.1
-- 生成日時:
-- サーバのバージョン: 10.4.10-MariaDB
-- PHP のバージョン: 7.3.12
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- データベース: `intra_mail`
--
-- --------------------------------------------------------
--
-- テーブルの構造 `mails`
--
CREATE TABLE `mails` (
`id` int(11) NOT NULL,
`m_to` int(11) NOT NULL,
`m_from` int(11) NOT NULL,
`subject` varchar(32) NOT NULL,
`content` text NOT NULL,
`sendtime` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- テーブルのデータのダンプ `mails`
--
INSERT INTO `mails` (`id`, `m_to`, `m_from`, `subject`, `content`, `sendtime`) VALUES
(1, 1, 2, 'どらやきあるよ', 'おいしいどらやきだよ。\r\nたくさんもらったよ。', '2020-02-21 05:52:36');
-- --------------------------------------------------------
--
-- テーブルの構造 `members`
--
CREATE TABLE `members` (
`id` int(11) NOT NULL,
`m_name` varchar(16) NOT NULL,
`password` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- テーブルのデータのダンプ `members`
--
INSERT INTO `members` (`id`, `m_name`, `password`) VALUES
(1, 'どらえもん', '$2y$10$UCVV6O7LCKn/.OCUIih7y.2..cF6620fKo.PPEaUPnBfu7M5n8m6S'),
(2, 'のび太', '$2y$10$03gU7/Cd.Vf4WEp.ub.5r.LoKEKXc1GHWWqILQcxCmU2wyNkaRwdS'),
(3, '静香', '$2y$10$85sag./ANAHlijv6tYX/e.W57sH5mX2Lx2ppVLwpe6jZx7AH.KYCa'),
(4, 'ジャイアン', '$2y$10$fpejrErvbtTFsuLmxfU9wuenwALyeZoZdg5usAInZVq7ttBpGXpae'),
(5, 'スネ夫', '$2y$10$VesWFcKp4LrUTvnxbTyr8OsPztbJMnyhi4fwYfIcGdvOTYcO1sXrO');
--
-- ダンプしたテーブルのインデックス
--
--
-- テーブルのインデックス `mails`
--
ALTER TABLE `mails`
ADD PRIMARY KEY (`id`);
--
-- テーブルのインデックス `members`
--
ALTER TABLE `members`
ADD PRIMARY KEY (`id`);
--
-- ダンプしたテーブルのAUTO_INCREMENT
--
--
-- テーブルのAUTO_INCREMENT `mails`
--
ALTER TABLE `mails`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
--
-- テーブルのAUTO_INCREMENT `members`
--
ALTER TABLE `members`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
構造