PHPMailer対応:PHPお問い合わせフォームの作り方|確認画面・メール送信付きサンプルコード


PHP お問い合わせフォームの作り方|確認画面・メール送信付きサンプルコード

PHPでお問い合わせフォームを作成する方法を解説します。
今回は、入力フォーム → 確認画面 → メール送信 → 送信完了画面 までの一連の流れをサンプルコード付きで紹介します。
初心者向けに分かりやすく解説するので、フォーム作成の参考にしてください!

📌サンプルページ


📌 完成イメージ

  1. index.php → ユーザーが入力するフォーム画面
  2. confirm.php → 入力内容を確認する画面
  3. thanks.php → メール送信後の完了画面

各ページ間では session を使ってデータを保持し、入力内容を confirm.php で確認後に thanks.php で送信します。


📌 PHPMailer 導入ステップ【PHPお問い合わせフォームにメール送信機能を追加】

✅ 準備:ComposerでPHPMailerをインストール

まずはPHPMailerをインストールします。
ターミナル(またはコマンドプロンプト)で以下を実行してください。

composer require phpmailer/phpmailer

📌 1. フォームの作成 (index.php)

まずは、ユーザーが情報を入力するフォーム画面を作成します。

📜 コード: index.php

<?php
session_start();

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
  // thanks.php 経由で戻ってきたときにセッションを初期化
  $_SESSION['form_data'] = [];
}

$form_data = isset($_SESSION['form_data']) ? $_SESSION['form_data'] : [];
?>


<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="contact.css">
    <title>お問い合わせフォーム</title>
    <style>
    .inline-group {
        display: flex;
        align-items: center;
        margin-bottom: 5px;
    }

    .inline-group label {
        margin-left: 10px;
        margin-right: 20px;
    }

    .color-preview {
        display: inline-block;
        width: 30px;
        height: 30px;
        border: 1px solid #000;
        margin-left: 10px;
    }
    </style>
    <script>
    function updateColorPreview() {
        var colorInput = document.getElementById('color');
        var colorPreview = document.getElementById('color-preview');
        colorPreview.style.backgroundColor = colorInput.value;
    }
    </script>
</head>

<body>
    <div class="container">
        <div class="form-wrapper">
            <div class="form-header">
                <h1>お問い合わせ</h1>
            </div>

            <form action="confirm.php" method="POST" enctype="multipart/form-data">
                <div class="form-group">
                    <label for="name">名前:</label>
                    <input type="text" id="name" name="name" class="form-control" required
                        value="<?php echo htmlspecialchars($form_data['name'] ?? ''); ?>">
                </div>

                <div class="form-group">
                    <label for="email">メールアドレス:</label>
                    <input type="email" id="email" name="email" class="form-control" required
                        value="<?php echo htmlspecialchars($form_data['email'] ?? ''); ?>">
                </div>

                <div class="form-group">
                    <label for="phone">電話番号:</label>
                    <input type="tel" id="phone" name="phone" class="form-control"
                        value="<?php echo htmlspecialchars($form_data['phone'] ?? ''); ?>">
                </div>

                <div class="form-group">
                    <label for="purpose">お問い合わせの目的:</label>
                    <select id="purpose" name="purpose" class="form-control">
                        <option value="" disabled <?php echo empty($form_data['purpose']) ? 'selected' : ''; ?>>選択してください
                        </option>
                        <option value="feedback"
                            <?php echo ($form_data['purpose'] ?? '') == 'feedback' ? 'selected' : ''; ?>>
                            フィードバック</option>
                        <option value="inquiry"
                            <?php echo ($form_data['purpose'] ?? '') == 'inquiry' ? 'selected' : ''; ?>>
                            一般的なお問い合わせ</option>
                        <option value="support"
                            <?php echo ($form_data['purpose'] ?? '') == 'support' ? 'selected' : ''; ?>>サポート依頼
                        </option>
                    </select>
                </div>

                <div class="form-group">
                    <label for="date">希望する連絡日:</label>
                    <input type="date" id="date" name="date" class="form-control"
                        value="<?php echo htmlspecialchars($form_data['date'] ?? ''); ?>">
                </div>

                <div class="form-group">
                    <label for="quantity">ご希望の数量:</label>
                    <input type="number" id="quantity" name="quantity" class="form-control" min="1" max="100"
                        value="<?php echo htmlspecialchars($form_data['quantity'] ?? ''); ?>">
                </div>

                <div class="form-group">
                    <label for="color">お気に入りの色:</label>
                    <input type="color" id="color" name="color" class="form-control"
                        value="<?php echo htmlspecialchars($form_data['color'] ?? '#000000'); ?>"
                        onchange="updateColorPreview()">
                    <div id="color-preview" class="color-preview"
                        style="background-color: <?php echo htmlspecialchars($form_data['color'] ?? '#000000'); ?>;">
                    </div>
                </div>

                <div class="form-group">
                    <label for="range">ご満足度:</label>
                    <input type="range" id="range" name="range" class="form-control" min="0" max="10"
                        value="<?php echo htmlspecialchars($form_data['range'] ?? '5'); ?>">
                </div>

                <div class="form-group">
                    <label>連絡方法:</label>
                    <div class="inline-group">
                        <input type="radio" id="email" name="contact_method" value="email"
                            <?php echo ($form_data['contact_method'] ?? 'email') == 'email' ? 'checked' : ''; ?>>
                        <label for="email">メール</label>
                        <input type="radio" id="phone" name="contact_method" value="phone"
                            <?php echo ($form_data['contact_method'] ?? '') == 'phone' ? 'checked' : ''; ?>>
                        <label for="phone">電話</label>
                        <input type="radio" id="either" name="contact_method" value="either"
                            <?php echo ($form_data['contact_method'] ?? '') == 'either' ? 'checked' : ''; ?>>
                        <label for="either">どちらでも</label>
                    </div>
                </div>

                <div class="form-group">
                    <label>興味のあるトピック:</label>
                    <div class="inline-group">
                        <input type="checkbox" id="news" name="topics[]" value="news"
                            <?php echo in_array('news', $form_data['topics'] ?? []) ? 'checked' : ''; ?>>
                        <label for="news">ニュース</label>
                        <input type="checkbox" id="updates" name="topics[]" value="updates"
                            <?php echo in_array('updates', $form_data['topics'] ?? []) ? 'checked' : ''; ?>>
                        <label for="updates">アップデート</label>
                        <input type="checkbox" id="offers" name="topics[]" value="offers"
                            <?php echo in_array('offers', $form_data['topics'] ?? []) ? 'checked' : ''; ?>>
                        <label for="offers">特別オファー</label>
                    </div>
                </div>

                <div class="form-group">
                    <label for="message">メッセージ:</label>
                    <textarea id="message" name="message" class="form-control"
                        rows="4"><?php echo htmlspecialchars($form_data['message'] ?? ''); ?></textarea>
                </div>

                <div class="form-footer">
                    <button type="submit" class="btn-submit">確認</button>
                </div>
            </form>
        </div>
    </div>
</body>

</html>

📌 コード解説

session_start();セッションを開始し、入力データを保持
method="POST" でデータを confirm.php に送信
htmlspecialchars()XSS攻撃を防止


📌 2. 確認画面 (confirm.php)

次に、ユーザーが入力した情報を確認する画面を作成します。

📜 コード: confirm.php

<?php
session_start();
ini_set('display_errors', 1);
error_reporting(E_ALL);

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $_SESSION['form_data'] = $_POST;
}

$form_data = $_SESSION['form_data'] ?? [];

// オプション定義
$purpose_options = [
    'feedback' => 'フィードバック',
    'inquiry' => '一般的なお問い合わせ',
    'support' => 'サポート依頼'
];

$contact_method_options = [
    'email' => 'メール',
    'phone' => '電話',
    'either' => 'どちらでも'
];

$topics_options = [
    'news' => 'ニュース',
    'updates' => 'アップデート',
    'offers' => '特別オファー'
];
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="contact.css">
    <title>確認画面</title>
</head>

<body>
    <div class="container">
        <div class="form-wrapper">
            <h1>確認画面</h1>

            <p><strong>名前:</strong> <?= htmlspecialchars($form_data['name'] ?? '未入力') ?></p>
            <p><strong>メールアドレス:</strong> <?= htmlspecialchars($form_data['email'] ?? '未入力') ?></p>
            <p><strong>電話番号:</strong> <?= htmlspecialchars($form_data['phone'] ?? '未入力') ?></p>
            <p><strong>お問い合わせの目的:</strong>
                <?php
                  $purpose_key = $form_data['purpose'] ?? null;
                  echo htmlspecialchars($purpose_options[$purpose_key] ?? '未選択');
                ?>
            </p>
            <p><strong>希望する連絡日:</strong> <?= htmlspecialchars($form_data['date'] ?? '未入力') ?></p>
            <p><strong>ご希望の数量:</strong> <?= htmlspecialchars($form_data['quantity'] ?? '未入力') ?></p>
            <p><strong>お気に入りの色:</strong>
                <span
                    style="display:inline-block;width:30px;height:30px;background-color:<?= htmlspecialchars($form_data['color'] ?? '#000000') ?>;"></span>
            </p>
            <p><strong>ご満足度:</strong> <?= htmlspecialchars($form_data['range'] ?? '未入力') ?></p>
            <?php
              $method_key = $form_data['contact_method'] ?? null;
              echo htmlspecialchars($contact_method_options[$method_key] ?? '未選択');
            ?>
            <p><strong>興味のあるトピック:</strong>
                <?php 
                  if (!empty($form_data['topics']) && is_array($form_data['topics'])) {
                      $selected_topics = array_map(function($topic) use ($topics_options) {
                          return $topics_options[$topic] ?? '不明なトピック';
                      }, $form_data['topics']);
                      echo htmlspecialchars(implode(", ", $selected_topics), ENT_QUOTES, 'UTF-8');
                  } else {
                      echo '選択なし';
                  }
                ?>
            </p>
            <p><strong>メッセージ:</strong><br>
                <?= nl2br(htmlspecialchars($form_data['message'] ?? '未入力')) ?>
            </p>

            <!-- thanks.phpへPOST送信。データとファイルを一緒に渡す -->
            <form action="thanks.php" method="POST" enctype="multipart/form-data">
                <?php foreach ($form_data as $key => $value): ?>
                <?php if (is_array($value)): ?>
                <?php foreach ($value as $v): ?>
                <input type="hidden" name="<?= htmlspecialchars($key, ENT_QUOTES, 'UTF-8') ?>[]"
                    value="<?= htmlspecialchars($v, ENT_QUOTES, 'UTF-8') ?>">
                <?php endforeach; ?>
                <?php else: ?>
                <input type="hidden" name="<?= htmlspecialchars($key, ENT_QUOTES, 'UTF-8') ?>"
                    value="<?= htmlspecialchars($value, ENT_QUOTES, 'UTF-8') ?>">
                <?php endif; ?>
                <?php endforeach; ?>

                <div class="form-group">
                    <label for="file">添付ファイル(任意):</label>
                    <input type="file" name="file" id="file">
                </div>

                <button type="submit" class="btn-submit">送信</button>
            </form>

            <form action="index.php" method="GET">
                <button type="submit" class="btn-back">戻る</button>
            </form>
        </div>
    </div>
</body>

</html>

📌 コード解説

$_SESSION['form_data'] = $_POST;フォームデータをセッションに保存
入力データを htmlspecialchars() でサニタイズ
thanks.php への送信ボタンと、index.php に戻るボタンを設置


📌 3. メール送信・完了画面 (thanks.php)

最後に、メールを送信し、送信完了メッセージを表示 します。

📜 コード: thanks.php

<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;

require 'vendor/autoload.php'; // ComposerでインストールしたPHPMailerを読み込む

// エラーレポート(開発時のみ有効に)
ini_set('display_errors', 1);
error_reporting(E_ALL);

// フォームデータをPOSTから受け取る
$form_data = $_POST;

// 日本語ラベル定義
$purpose_options = [
    'feedback' => 'フィードバック',
    'inquiry' => '一般的なお問い合わせ',
    'support' => 'サポート依頼'
];

$topics_options = [
    'news' => 'ニュース',
    'updates' => 'アップデート',
    'offers' => '特別オファー'
];

$purpose_key = $form_data['purpose'] ?? '';
$purpose_jp = $purpose_options[$purpose_key] ?? '未選択';

$topics_jp = '選択なし';
if (!empty($form_data['topics']) && is_array($form_data['topics'])) {
    $selected_topics = array_map(function($topic) use ($topics_options) {
        return $topics_options[$topic] ?? '不明なトピック';
    }, $form_data['topics']);
    $topics_jp = implode(", ", $selected_topics);
}

// メール本文の作成
$message = <<<EOT
名前: {$form_data['name']}
メールアドレス: {$form_data['email']}
電話番号: {$form_data['phone']}
お問い合わせの目的: {$purpose_jp}
希望する連絡日: {$form_data['date']}
ご希望の数量: {$form_data['quantity']}
お気に入りの色: {$form_data['color']}
ご満足度: {$form_data['range']}
連絡方法: {$form_data['contact_method']}
興味のあるトピック: {$topics_jp}
メッセージ:
{$form_data['message']}
EOT;

// メール送信処理(PHPMailer)
$mail_success = false;

$mail = new PHPMailer(true);

try {
    // SMTP設定(←適宜変更してください)
    $mail->isSMTP();
    $mail->Host = 'smtp.example.com'; // 例:smtp.gmail.com
    $mail->SMTPAuth = true;
    $mail->Username = 'your@example.com'; // 送信元アカウント
    $mail->Password = 'yourpassword';     // パスワード(アプリパスワード推奨)
    $mail->SMTPSecure = 'tls';            // ssl or tls
    $mail->Port = 587;

    // メールヘッダ
    $mail->CharSet = 'UTF-8';
    $mail->Encoding = 'base64';
    $mail->setFrom('your@example.com', 'お問い合わせフォーム');
    $mail->addAddress('test@sample.com', '受信者名'); // 送信先

    // 本文
    $mail->Subject = 'お問い合わせフォームからのメッセージ';
    $mail->Body = $message;

    // 添付ファイル(あれば)
    if (!empty($_FILES['file']['tmp_name']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
        $mail->addAttachment($_FILES['file']['tmp_name'], $_FILES['file']['name']);
    }

    $mail->send();
    $mail_success = true;
} catch (Exception $e) {
    error_log('メール送信失敗: ' . $mail->ErrorInfo);
}

// セッションを完全にクリア(これを追加)
session_start();
session_unset();
session_destroy();
?>

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="contact.css">
    <title>送信完了</title>
</head>

<body>
    <div class="container">
        <div class="form-wrapper">
            <h1>送信完了</h1>
            <?php if ($mail_success): ?>
            <p>お問い合わせいただきありがとうございます。</p>
            <p>担当者よりご連絡いたしますので、しばらくお待ちください。</p>
            <?php else: ?>
            <p>申し訳ありませんが、メールの送信に失敗しました。</p>
            <p>再度お試しいただくか、別の方法でご連絡ください。</p>
            <?php endif; ?>

            <form action="index.php" method="GET">
                <button type="submit">トップページへ戻る</button>
            </form>
        </div>
    </div>
</body>

</html>

📌 コード解説


$_SESSION['form_data'] がない場合は index.php にリダイレクトし、不正アクセスを防止
PHPMailer ライブラリを使って、入力データをメールとして送信
✅ メール送信後は session_unset()session_destroy() でセッションをクリアし、再送信を防止
✉️ 送信先のメールアドレスやSMTP設定は、$mail->addAddress()$mail->Host などで設定します

下記メールアドレスを変更してから、テストサーバーにアップして動作確認してみましょう。


🎯 まとめ

ステップ解説
index.php (フォーム入力画面)ユーザーが入力し、confirm.php にデータ送信
confirm.php (確認画面)入力内容を表示し、thanks.php に送信
thanks.php (送信完了画面)メール送信後、完了メッセージを表示

🚀 これでお問い合わせフォームが完成!

フォーム入力 → 確認画面 → メール送信 → 完了画面 の流れが実装できました!
📢 このコードを活用し、自分のサイトにお問い合わせフォームを実装してみましょう! 🚀✨

Githubサンプルコード

✪ 画像素材がないものはランダムで表示されるようになっています。フリー素材などでご用意ください。

おすすめChromeプラグイン一覧

プラグイン名特徴
GoFullPageウェブページ全体のスクリーンショットを簡単に取得できるブラウザ拡張機能です。
ColorZilla色を抽出するための拡張機能です。
WhatFontウェブページ上のフォントの情報を簡単に確認できるブラウザ拡張機能です。
PerfectPixelデザイナーが作成したデザインと実際にコーディングされたウェブページがどの程度一致しているかを確認・調整するためのブラウザ拡張機能です。

模写の手順

ステップ内容
ステップ 1構図を手書きか全画面スクショ(Go full page等)した後、ペイントツールで四角で囲い、大まかなclass,命名規則をあらかじめ決める。
ステップ 2HTMLの基本構造を作成する
ステップ 3CSSでレイアウトを模写する
ステップ 4 中級〜JavaScriptを追加して動きを再現する
ステップ 5最終調整を行い、検証ツールやPerfectPixel(chromeプラグイン)などで完成を確認する。