PHP・JS・CSSで作成
クライアント側で氏名、ID、メールアドレスを入力した内容をサーバー登録後、入力内容を自動返信(メール)する仕様です。
すべてのファイルはコードのコピペ可能です ※コードの修正・追加・削除・UI等の変更などの制限はありません。



| ファイル |
| index.php confirm.php complete.php config.php db.php register.php script.js style.css |
| GitHub PHPMailerコード |
| ダウンロードURL https://github.com/PHPMailer/PHPMailer?utm_source=chatgpt.com |
| PHPMailer-master.zipの圧縮ファイル解凍後、PHPMailer-master→src→Exception.php PHPMailer.php SMTP.phpの3ファイルをコピー PHPMailerフォルダーを作成して3ファイルを中に入れる Exception.php PHPMailer.php SMTP.php |
| ファイル階層 (例) |
| public_html/ └── registration/ │ ├── config.php ←セキュリティ対策でアクセス不可の配置で ├── db.php ├── index.php ├── confirm.php ├── register.php ├── complete.php ├── script.js ├── style.css │ └── PHPMailer/ └── src/ ├── Exception.php ├── PHPMailer.php └── SMTP.php |
| MySQLデータベース、MySQL用ユーザーの作成 |
| phpMyAdminでMySQLやMariaDBデータベースを操作するため、オープンソースのWebツールを使用 phpMyAdminまたはMySQL設定はレンタルサーバーにインストールされている場合があります。 データベース registrationdb MySQLユーザーreguser テーブルregistrations |
| phpMyAdminの設定例 |


テーブルの登録データ削除(個別・全て)はphpMyAdmin内で削除できます。
| index.php |
<?php
require_once __DIR__ . '/config.php';
// CSRFトークン作成
if (empty($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] =
bin2hex(random_bytes(32));
}
function h($value): string
{
return htmlspecialchars(
(string)$value,
ENT_QUOTES,
'UTF-8'
);
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= h(SITE_NAME) ?></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<?php if (!empty($_SESSION['error_message'])): ?>
<p class="error"><?= h($_SESSION['error_message']) ?></p>
<?php unset($_SESSION['error_message']); ?>
<?php endif; ?>
<h1>予約登録受付</h1>
<form action="confirm.php"
method="post"
id="registrationForm">
<!-- CSRF対策 -->
<input type="hidden"
name="csrf_token"
value="<?= h($_SESSION['csrf_token']) ?>">
<!-- 予約登録 -->
<div class="form-group">
<div class="reservation-type">予約登録</div>
</div>
<!-- 氏名 -->
<div class="form-group">
<label for="name">氏名</label>
<input type="text"
id="name"
name="name"
maxlength="100"
required
placeholder="山田 太郎">
</div>
<!-- ID -->
<div class="form-group">
<label for="user_id">ID(数字6桁)</label>
<input type="text"
id="user_id"
name="user_id"
inputmode="numeric"
maxlength="6"
pattern="[0-9]{6}"
required
placeholder="123456">
<p class="help">半角数字6桁で入力してください。</p>
</div>
<!-- メールアドレス -->
<div class="form-group">
<label for="email">メールアドレス</label>
<input type="email"
id="email"
name="email"
maxlength="255"
required
placeholder="example@example.com">
</div>
<!-- 確認ボタン -->
<button type= "submit"class="submit-button">確認する</button>
</form>
</div>
<script src="script.js"></script>
</body>
</html>| confirm.php |
<?php
require_once __DIR__ . '/config.php';
function h($value): string
{
return htmlspecialchars(
(string)$value,
ENT_QUOTES,
'UTF-8'
);
}
/*POST以外は登録画面へ戻す*/
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: index.php');
exit;
}
/*CSRFチェック*/
$csrf = $_POST['csrf_token'] ?? '';
if (
empty($_SESSION['csrf_token']) ||
!hash_equals(
$_SESSION['csrf_token'],
$csrf
)
) {
exit('不正なアクセスです。');
}
/*入力値取得*/
$name = trim($_POST['name'] ?? '');
$userId = trim($_POST['user_id'] ?? '');
$email = trim($_POST['email'] ?? '');
/*氏名チェック*/
if ($name === '') {
exit('氏名を入力してください。');
}
/*IDチェック*/
if (!preg_match(
'/^[0-9]{6}$/',
$userId
)) {
exit(
'IDは数字6桁で入力してください。'
);
}
/*メールアドレスチェック*/
if (!filter_var(
$email,
FILTER_VALIDATE_EMAIL
)) {
exit(
'メールアドレスが正しくありません。'
);
}
/*登録種別は予約登録で固定*/
$registrationType = '予約登録';
/*入力内容をセッションに保存*/
$_SESSION['form'] = [
'registration_type' =>
$registrationType,
'name' =>
$name,
'user_id' =>
$userId,
'email' =>
$email
];
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>予約内容確認</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>予約内容確認</h1>
<p class="notice">以下の内容で予約登録します。</p>
<div class="confirm-box">
<div class="confirm-row">
<span>氏名</span>
<strong><?= h($name) ?></strong>
</div>
<div class="confirm-row">
<span>ID</span>
<strong><?= h($userId) ?></strong>
</div>
<div class="confirm-row">
<span>メールアドレス</span>
<strong><?= h($email) ?></strong>
</div>
</div>
<div class="button-area">
<!-- 戻る -->
<form action="index.php" method="get">
<button type="submit"class="back-button">戻る</button>
</form>
<!-- 予約登録する -->
<form action="register.php"
method="post">
<input type="hidden"
name="csrf_token"
value="<?= h(
$_SESSION['csrf_token']
) ?>">
<button type= "submit"class="submit-button">予約登録する</button>
</form>
</div>
</div>
</body>
</html>| complete.php |
<?php
require_once __DIR__ . '/config.php';
function h($value): string
{
return htmlspecialchars(
(string)$value,
ENT_QUOTES,
'UTF-8'
);
}
/*登録完了情報を取得*/
$complete = $_SESSION['complete'] ?? null;
/*完了情報がなければ登録画面へ*/
if (!$complete) {
header('Location: index.php');
exit;
}
/*完了情報を取得*/
$registrationId = $complete['registration_id'];
$name = $complete['name'];
$email = $complete['email'];
/*表示後にセッションから削除*/
unset($_SESSION['complete']);
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登録完了</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="complete">
<h1>登録完了</h1>
<p>登録が完了しました。</p>
<div class="registration-number">
<p>登録番号</p>
<strong><?= h($registrationId) ?></strong>
</div>
<p><?= h($name) ?> 様</p>
<p>登録ありがとうございました。</p>
<p>登録メールアドレス<br><strong><?= h($email) ?></strong></p>
<a href= "index.php"class="home-button">登録画面へ戻る</a>
</div>
</div>
</body>
</html>| config.php |
<?php
session_start();
define('DB_HOST', 'データベースのサーバー名');
define('DB_NAME', '使用するデータベース名');
define('DB_USER', 'データベースのユーザー名');
define('DB_PASS', 'データベースのパスワード');
define('MAIL_FROM', '送信元として使用するメールアドレス');
define('MAIL_FROM_NAME', '登録受付システム');
define('SMTP_HOST', 'SMTPサーバー名');
define('SMTP_PORT', SMTPポート番号);
define('SMTP_USER', 'SMTP認証用ユーザー名');
define('SMTP_PASSWORD', 'SMTP認証用パスワード');
define('SITE_NAME', '登録受付システム');
date_default_timezone_set('Asia/Tokyo');
//==============例========================
<?php
session_start();
// データベース設定
define('DB_HOST', 'localhost');
define('DB_NAME', 'registration_db');
define('DB_USER', 'registration_user');
define('DB_PASS', 'abc123');
// メール送信元設定
define('MAIL_FROM', 'info@example.com');
define('MAIL_FROM_NAME', '登録受付システム');
// SMTP設定
define('SMTP_HOST', 'smtp.example.com');
define('SMTP_PORT', 465);
define('SMTP_USER', 'info@example.com');
define('SMTP_PASSWORD', 'mailpass123');
// サイト名
define('SITE_NAME', '登録受付システム');
// 日本時間
date_default_timezone_set('Asia/Tokyo');| db.php |
<?php
require_once __DIR__ . '/config.php';
function getPDO(): PDO
{
static $pdo = null;
if ($pdo === null) {
$dsn = 'mysql:host=' . DB_HOST .
';dbname=' . DB_NAME .
';charset=utf8mb4';
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new PDO(
$dsn,
DB_USER,
DB_PASS,
$options
);
}
return $pdo;
}| register.php |
<?php
require_once __DIR__ . '/config.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/PHPMailer/src/Exception.php';
require_once __DIR__ . '/PHPMailer/src/PHPMailer.php';
require_once __DIR__ . '/PHPMailer/src/SMTP.php';
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
/*POST以外は禁止*/
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: index.php');
exit;
}
/*CSRFチェック*/
$csrf = $_POST['csrf_token'] ?? '';
if (
empty($_SESSION['csrf_token']) ||
!hash_equals(
$_SESSION['csrf_token'],
$csrf
)
) {
exit('不正なアクセスです。');
}
/*セッションから入力データを取得*/
$form = $_SESSION['form'] ?? null;
if (!$form) {
header('Location: index.php');
exit;
}
$registrationType = '予約登録';
$name = $form['name'];
$userId = $form['user_id'];
$email = $form['email'];
if (!preg_match(
'/^[0-9]{6}$/',
$userId
)) {
exit(
'IDが不正です。'
);
}
if (!filter_var(
$email,
FILTER_VALIDATE_EMAIL
)) {
exit(
'メールアドレスが不正です。'
);
}
try {
/*データベース接続*/
$pdo = getPDO();
/*同じIDが登録済みか確認 */
$stmt = $pdo->prepare(
'SELECT id
FROM registrations
WHERE user_id = ?
LIMIT 1'
);
$stmt->execute([
$userId
]);
if ($stmt->fetch()) {
$_SESSION['error_message'] = 'このIDはすでに予約登録されています。';
header('Location: index.php');
exit;
}
/* 登録*/
$stmt = $pdo->prepare(
'INSERT INTO registrations
(
registration_type,
user_id,
name,
email
)
VALUES (?, ?, ?, ?)'
);
$stmt->execute([
$registrationType,
$userId,
$name,
$email
]);
/*登録番号を取得*/
$registrationId =
$pdo->lastInsertId();
/*登録完了メール送信*/
try {
$mail = new PHPMailer(true);
/*SMTP設定*/
$mail->isSMTP();
$mail->Host = SMTP_HOST;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USER;
$mail->Password = SMTP_PASSWORD;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = SMTP_PORT;
/*文字コード*/
$mail->CharSet = 'UTF-8';
/*送信元*/
$mail->setFrom(
MAIL_FROM,
MAIL_FROM_NAME
);
/*登録者のメールアドレス*/
$mail->addAddress(
$email,
$name
);
/*件名*/
$mail->Subject = '登録受付のお知らせ';
/*登録日時*/
$registrationDate = date('Y年m月d日 H:i:s');
/*メール本文*/
$mail->Body =
$name . " 様\n\n" .
"登録を受け付けました。\n\n" .
"以下の内容で登録されています。\n\n" .
"--------------------------------\n" .
"登録番号:"
. $registrationId . "\n" .
"登録種別:"
. $registrationType . "\n" .
"氏名:"
. $name . "\n" .
"ID:"
. $userId . "\n" .
"メールアドレス:"
. $email . "\n" .
"登録日時:"
. $registrationDate . "\n" .
"--------------------------------\n\n" .
"このメールは登録受付システムから\n" .
"自動送信されています。\n\n" .
MAIL_FROM_NAME;
/*テキストメール*/
$mail->isHTML(false);
/*メール送信*/
$mail->send();
} catch (Exception $e) {
/*メール送信失敗をログに記録*/
error_log(
'登録完了メール送信失敗:'
. $mail->ErrorInfo
);
}
/*登録完了情報をセッションに保存*/
$_SESSION['complete'] = [
'registration_id' =>
$registrationId,
'registration_type' =>
$registrationType,
'name' =>
$name,
'user_id' =>
$userId,
'email' =>
$email
];
/*入力データを削除*/
unset($_SESSION['form']);
/*完了画面へ*/
header('Location: complete.php');
exit;
} catch (PDOException $e) {
/*エラー内容はログへ*/
error_log($e->getMessage());
/*ユーザーには詳細を見せない*/
exit(
'登録処理中にエラーが発生しました。'
);
}| script.js |
document.addEventListener(
'DOMContentLoaded',
function () {
const form =
document.getElementById(
'registrationForm'
);
const userId =
document.getElementById(
'user_id'
);
/*IDは数字だけ*/
userId.addEventListener(
'input',
function () {
this.value =
this.value.replace(
/[^0-9]/g,
''
);
if (this.value.length > 6) {
this.value =
this.value.substring(
0,
6
);
}
}
);
/*送信前チェック*/
form.addEventListener(
'submit',
function (event) {
let valid = true;
if (
!/^[0-9]{6}$/.test(
userId.value
)
) {
alert(
'IDは数字6桁で入力してください。'
);
valid = false;
}
if (!valid) {
event.preventDefault();
}
}
);
}
);| style.css |
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
background: #f5f5f5;
color: #333;
font-family:
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
"Noto Sans JP",
sans-serif;
}
.container {
width: 90%;
max-width: 650px;
margin: 50px auto;
padding: 35px;
background: #fff;
border-radius: 10px;
box-shadow:
0 3px 15px rgba(0, 0, 0, 0.08);
}
h1 {
margin-top: 0;
margin-bottom: 30px;
text-align: center;
font-size: 28px;
}
.form-group {
margin-bottom: 25px;
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
input[type="text"],
input[type="email"] {
width: 100%;
padding: 13px;
border: 1px solid #ccc;
border-radius: 5px;
font-size: 16px;
}
input:focus {
outline: none;
border-color: #555;
}
.help {
margin-top: 6px;
font-size: 13px;
color: #777;
}
.type-buttons {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.type-button {
padding: 12px 20px;
border: 1px solid #aaa;
background: #fff;
border-radius: 5px;
cursor: pointer;
font-size: 15px;
}
.type-button:hover {
background: #f0f0f0;
}
.type-button.selected {
background: #333;
color: #fff;
border-color: #333;
}
.submit-button {
width: 100%;
padding: 15px;
border: none;
border-radius: 5px;
background: #333;
color: #fff;
font-size: 17px;
cursor: pointer;
}
.submit-button:hover {
opacity: 0.85;
}
.error {
color: #d00;
font-size: 14px;
}
.notice {
text-align: center;
margin-bottom: 25px;
}
.confirm-box {
border: 1px solid #ddd;
border-radius: 5px;
}
.confirm-row {
display: flex;
padding: 15px;
border-bottom: 1px solid #eee;
}
.confirm-row:last-child {
border-bottom: none;
}
.confirm-row span {
width: 40%;
font-weight: bold;
}
.confirm-row strong {
width: 60%;
word-break: break-all;
}
.button-area {
display: flex;
gap: 15px;
justify-content: center;
margin-top: 30px;
}
.button-area form {
flex: 1;
}
.back-button {
width: 100%;
padding: 15px;
border: 1px solid #aaa;
border-radius: 5px;
background: #fff;
cursor: pointer;
font-size: 16px;
}
.button-area .submit-button {
width: 100%;
}
@media (max-width: 600px) {
.button-area {
flex-direction: column;
}
.confirm-row {
display: block;
}
.confirm-row span,
.confirm-row strong {
display: block;
width: 100%;
}
.confirm-row strong {
margin-top: 5px;
}
}
.complete {
text-align: center;
padding: 20px 10px;
}
.complete h1 {
margin-bottom: 30px;
}
.complete p {
line-height: 2;
}
.registration-number {
margin: 25px auto;
padding: 20px;
background: #f5f5f5;
border-radius: 5px;
}
.registration-number p {
margin: 0 0 5px;
font-size: 14px;
}
.registration-number strong {
font-size: 28px;
letter-spacing: 2px;
}
.home-button {
display: inline-block;
margin-top: 25px;
padding: 13px 30px;
background: #333;
color: #fff;
text-decoration: none;
border-radius: 5px;
}
.home-button:hover {
opacity: 0.85;
}
.reservation-type {
padding: 13px;
background: #f5f5f5;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
font-weight: bold;
}| 登録返信メール内容 例 |
| 登録受付のお知らせ test 様 登録を受け付けました。 以下の内容で登録されています。 登録番号:1 登録種別:予約登録 氏名:test ID:123456 メールアドレス:tesst@gmail.com 登録日時:2026年08月14日 02:12:37 このメールは登録受付システムから 自動送信されています。 登録受付システム |
以上です。
