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
このメールは登録受付システムから
自動送信されています。
登録受付システム

以上です。