Webサイトに欠かせない機能の一つが「お問い合わせフォーム」です。ユーザーからの質問やフィードバックを受け付ける窓口として、非常に重要な役割を果たします。
今回は、PHPを使って、入力フォームの表示、入力値の検証(バリデーション)、そして自動返信メールの送信までを、1つのPHPファイルで完結させる方法を、ステップバイステップで解説します。
セキュリティと信頼性を考慮した、モダンで実践的なコードを作成していきましょう。
1. お問い合わせフォームの全体像と流れ
今回作成するcontact.php
ファイルは、以下のように動作します。
- 初回アクセス時 (GET): ユーザーがお問い合わせフォームのページを最初に開くと、入力フォームが表示されます。
- 送信ボタン押下時 (POST): ユーザーが内容を入力して送信ボタンを押すと、ページは自分自身にデータを送信します。
- データ受信とバリデーション: PHPは送信されたデータ(
$_POST
)を受け取り、「必須項目が入力されているか」「メールアドレスの形式は正しいか」などをチェックします。 - 処理の分岐:
- バリデーションエラーがある場合: エラーメッセージと共に、入力された内容を保持したままフォームを再表示します。
- バリデーションOKの場合: 自動返信メールを送信し、「送信完了」メッセージを表示します。
2. バリデーション(入力値の検証)の実装
安全なフォームを作る上で最も重要なのが、サーバーサイドでのバリデーションです。
2.1. 必須項目のチェック
名前やお問い合わせ内容が空でないかを確認します。trim()
関数で前後の空白を取り除いてからempty()
でチェックするのが確実です。
2.2. メールアドレス形式のチェック
メールアドレスの形式が正しいかどうかの検証には、複雑な正規表現を書くよりも、PHPに組み込まれているfilter_var()
関数を使うのが現代のベストプラクティスです。
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'メールアドレスの形式が正しくありません。';
}
2.3. エラーメッセージの管理
各項目で発生したエラーは、$errors
という配列にまとめて管理すると、後で表示する際に便利です。
3. メールの送信(PHPMailerの利用を推奨)
PHPのmb_send_mail()
関数でもメールは送れますが、迷惑メールに判定されやすかったり、サーバー設定に依存したりと、確実性に欠ける場合があります。
そのため、実運用ではPHPMailerのような信頼性の高いメール送信ライブラリを使用することを強く推奨します。以下の完成版コードでは、mb_send_mail()
を使った基本的な例を示しますが、より本格的な開発ではライブラリの導入を検討してください。
4. 完成版コード
これまでの要素をすべて盛り込んだ、1ファイルで完結するお問い合わせフォームのコードです。
【contact.php
】
<?php
// ===== 変数の初期化 =====
$name = '';
$email = '';
$inquiry = '';
$errors = [];
$message = '';
// ===== POSTリクエストがあった場合の処理 =====
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 入力値を取得し、前後の空白を削除
$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');
$inquiry = trim($_POST['inquiry'] ?? '');
// ===== バリデーション =====
if ($name === '') {
$errors['name'] = 'お名前を入力してください。';
}
if ($email === '') {
$errors['email'] = 'メールアドレスを入力してください。';
} elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'メールアドレスの形式が正しくありません。';
}
if ($inquiry === '') {
$errors['inquiry'] = 'お問い合わせ内容を入力してください。';
}
// ===== エラーがなかった場合のメール送信処理 =====
if (empty($errors)) {
// --- 自動返信メールの送信 ---
mb_language("Japanese");
mb_internal_encoding("UTF-8");
$subject = "【自動返信】お問い合わせありがとうございます";
$body = <<<EOM
{$name}様
この度は、お問い合わせいただき誠にありがとうございます。
以下の内容でお問い合わせを受け付けました。
================================
■ お名前:
{$name}
■ メールアドレス:
{$email}
■ お問い合わせ内容:
{$inquiry}
================================
内容を確認の上、担当者より改めてご連絡いたします。
EOM;
$headers = "From: your_sender_email@example.com"; // 送信元
if (mb_send_mail($email, $subject, $body, $headers)) {
$message = 'お問い合わせを受け付けました。確認メールを送信しておりますのでご確認ください。';
// 成功したら入力値をクリア
$name = $email = $inquiry = '';
} else {
$errors['mail'] = "メールの送信に失敗しました。";
}
}
}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>お問い合わせフォーム</title>
<style>
body { font-family: sans-serif; }
.container { max-width: 600px; margin: 30px auto; padding: 20px; border: 1px solid #ccc; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; }
input[type="text"], input[type="email"], textarea {
width: 100%; padding: 8px; box-sizing: border-box;
}
.error { color: #d9534f; font-size: 0.9em; }
.success-message { color: #5cb85c; border: 1px solid #5cb85c; padding: 15px; }
</style>
</head>
<body>
<div class="container">
<h1>お問い合わせ</h1>
<?php if ($message): ?>
<p class="success-message"><?php echo htmlspecialchars($message, ENT_QUOTES, 'UTF-8'); ?></p>
<?php endif; ?>
<?php if (!empty($errors['mail'])): ?>
<p class="error"><?php echo htmlspecialchars($errors['mail'], ENT_QUOTES, 'UTF-8'); ?></p>
<?php endif; ?>
<form action="" method="POST">
<div class="form-group">
<label for="name">お名前(必須)</label>
<input type="text" id="name" name="name" value="<?php echo htmlspecialchars($name, ENT_QUOTES, 'UTF-8'); ?>">
<?php if (!empty($errors['name'])): ?>
<p class="error"><?php echo $errors['name']; ?></p>
<?php endif; ?>
</div>
<div class="form-group">
<label for="email">メールアドレス(必須)</label>
<input type="email" id="email" name="email" value="<?php echo htmlspecialchars($email, ENT_QUOTES, 'UTF-8'); ?>">
<?php if (!empty($errors['email'])): ?>
<p class="error"><?php echo $errors['email']; ?></p>
<?php endif; ?>
</div>
<div class="form-group">
<label for="inquiry">お問い合わせ内容(必須)</label>
<textarea id="inquiry" name="inquiry" rows="6"><?php echo htmlspecialchars($inquiry, ENT_QUOTES, 'UTF-8'); ?></textarea>
<?php if (!empty($errors['inquiry'])): ?>
<p class="error"><?php echo $errors['inquiry']; ?></p>
<?php endif; ?>
</div>
<input type="submit" value="送信する">
</form>
</div>
</body>
</html>
5. ユーザーへのフィードバック
- エラーメッセージ:
$errors
配列に格納したメッセージを、各入力欄の下に表示します。 - 入力値の保持: エラー発生時、
value
属性にPHP変数をhtmlspecialchars()
で出力することで、ユーザーが入力した内容をフォームに復元します。これにより、ユーザーは再入力の手間が省けます。 - 成功メッセージ: メール送信に成功したら、フォームの上に完了メッセージを表示します。
まとめ
今回は、PHPでお問い合わせフォームを安全に実装する一連の流れを解説しました。
【重要ポイントの振り返り】
- バリデーションはサーバーサイドで必ず行う。特にメール形式は
filter_var()
が便利。 - エラーが発生してもユーザーが再入力しやすいよう、入力値をフォームに復元する。
- 画面にユーザーの入力値を表示する際は、必ず
htmlspecialchars()
でXSS対策を行う。 - 確実なメール送信のため、本番環境ではPHPMailerなどのライブラリ導入を検討する。
このパターンは、あらゆるWebフォーム開発の基本となります。ぜひこのコードを元に、自分だけのフォームをカスタマイズしてみてください。