WordPress お問い合わせフォーム完全ガイド【プラグイン・自作対応】


WordPressサイトにお問い合わせフォームを設置することは、ビジネスサイトや個人ブログにとって必須の要素です。訪問者からの貴重な声を集める窓口であり、信頼関係を築く重要なツールとなります。
はじめに — なぜフォームが要る?
WordPressサイトにお問い合わせフォームを設置することは、ビジネスサイトや個人ブログにとって必須の要素です。訪問者からの貴重な声を集める窓口であり、信頼関係を築く重要なツールとなります。
メール直書きのリスク/フォームのメリット(スパム防止・情報整理・UX)
メール直書きのリスク:
- メールアドレスが丸見えでスパムの標的になる
- ユーザーがメーラーを起動する手間がかかる
- 情報の入力漏れが多発
- 管理者側での整理・分類が困難
フォームのメリット:
- スパム防止: reCAPTCHAやHoneypotで自動投稿を防げる
- 情報整理: 必要な項目を事前に設定して抜け漏れを防止
- UX向上: ブラウザ上で簡単に送信でき、離脱率を下げる
- データ管理: 送信内容を構造化して保存・検索可能
- 自動化: 自動返信メールで即座に受付確認
初心者向け — プラグインで最短実装
プラグインを使えば、コードを書かずに本格的なお問い合わせフォームを作成できます。
Contact Form 7(インストール→基本フォーム→ショートコード設置)
インストール手順:
- WordPress管理画面→プラグイン→新規追加
- 「Contact Form 7」を検索してインストール・有効化
- 左メニューに「お問い合わせ」が追加される
設置方法:
- フォーム作成後、ショートコードをコピー
- 固定ページまたは投稿に
- ページを公開
WPForms(ドラッグ&ドロップ作成→埋め込み)
特徴:
- 直感的なドラッグ&ドロップ操作
- リアルタイムプレビュー機能
- テンプレートが豊富
基本的な使い方:
- WPFormsをインストール・有効化
- WPForms→新規追加
- 「Simple Contact Form」テンプレートを選択
- 必要に応じてフィールドを追加・編集
- 「埋め込み」からショートコードを取得して設置
Flamingo(送信データの保存)
Contact Form 7と組み合わせて使用するデータ保存プラグインです。
設定手順:
- Flamingoをインストール・有効化
- 管理画面→Flamingo→受信メッセージで送信内容を確認
- アドレス帳機能で送信者情報を自動管理
- CSVエクスポート機能で外部システムとの連携も可能
中級者向け — プラグインなしで自作
自作フォームなら完全にカスタマイズでき、サイトの読み込み速度向上にも貢献します。
HTML(必須項目・アクセシビリティ配慮)
<form method="post" action="">
<?php wp_nonce_field('contact_form_nonce', 'contact_nonce'); ?>
<div class="form-group">
<label for="contact_name">お名前 <span class="required">*</span></label>
<input type="text" id="contact_name" name="contact_name" required aria-describedby="name-error">
<div id="name-error" class="error-message" role="alert"></div>
</div>
<div class="form-group">
<label for="contact_email">メールアドレス <span class="required">*</span></label>
<input type="email" id="contact_email" name="contact_email" required aria-describedby="email-error">
<div id="email-error" class="error-message" role="alert"></div>
</div>
<div class="form-group">
<label for="contact_subject">件名</label>
<input type="text" id="contact_subject" name="contact_subject">
</div>
<div class="form-group">
<label for="contact_message">メッセージ <span class="required">*</span></label>
<textarea id="contact_message" name="contact_message" required aria-describedby="message-error"></textarea>
<div id="message-error" class="error-message" role="alert"></div>
</div>
<!-- Honeypot(非表示フィールド) -->
<input type="text" name="honey_pot" style="display:none;">
<button type="submit" name="submit_contact">送信する</button>
</form>
Code language: HTML, XML (xml)
PHP(Nonce・サニタイズ・wp_mail()
・自動返信)
<?php
// functions.phpまたは専用ファイルに追加
function handle_contact_form() {
if (!isset($_POST['submit_contact'])) {
return;
}
// Nonce検証
if (!wp_verify_nonce($_POST['contact_nonce'], 'contact_form_nonce')) {
wp_die('セキュリティエラーが発生しました。');
}
// Honeypotチェック
if (!empty($_POST['honey_pot'])) {
return; // スパムとして無視
}
// データのサニタイズ
$name = sanitize_text_field($_POST['contact_name']);
$email = sanitize_email($_POST['contact_email']);
$subject = sanitize_text_field($_POST['contact_subject']);
$message = sanitize_textarea_field($_POST['contact_message']);
// バリデーション
$errors = array();
if (empty($name)) {
$errors[] = 'お名前は必須です。';
}
if (empty($email) || !is_email($email)) {
$errors[] = 'メールアドレスを正しく入力してください。';
}
if (empty($message)) {
$errors[] = 'メッセージは必須です。';
}
if (!empty($errors)) {
// エラー表示処理
return;
}
// メール送信
$to = get_option('admin_email');
$mail_subject = 'お問い合わせ: ' . $subject;
$mail_message = "お名前: {$name}\n";
$mail_message .= "メールアドレス: {$email}\n";
$mail_message .= "件名: {$subject}\n\n";
$mail_message .= "メッセージ:\n{$message}";
$headers = array(
'From: ' . $name . ' <' . $email . '>',
'Reply-To: ' . $email
);
$sent = wp_mail($to, $mail_subject, $mail_message, $headers);
if ($sent) {
// 自動返信メール
$auto_subject = 'お問い合わせを受け付けました';
$auto_message = $name . "様\n\n";
$auto_message .= "お問い合わせいただき、ありがとうございます。\n";
$auto_message .= "内容を確認後、担当者よりご連絡いたします。\n\n";
$auto_message .= "送信内容:\n" . $mail_message;
wp_mail($email, $auto_subject, $auto_message, 'From: ' . get_bloginfo('name'));
// 成功メッセージ
echo '<div class="success-message">送信が完了しました。</div>';
} else {
echo '<div class="error-message">送信に失敗しました。しばらく後に再度お試しください。</div>';
}
}
add_action('init', 'handle_contact_form');
?>
Code language: HTML, XML (xml)
CSS(最低限の見た目)
.form-group {
margin-bottom: 1.5rem;
}
.form-group label {
display: block;
margin-bottom: 0.5rem;
font-weight: bold;
}
.required {
color: #e74c3c;
}
.form-group input[type="text"],
.form-group input[type="email"],
.form-group textarea {
width: 100%;
padding: 0.75rem;
border: 2px solid #ddd;
border-radius: 4px;
font-size: 1rem;
}
.form-group input:focus,
.form-group textarea:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 0 3px rgba(52, 152, 219, 0.1);
}
.form-group textarea {
min-height: 120px;
resize: vertical;
}
button[type="submit"] {
background-color: #3498db;
color: white;
padding: 1rem 2rem;
border: none;
border-radius: 4px;
font-size: 1rem;
cursor: pointer;
transition: background-color 0.3s;
}
button[type="submit"]:hover {
background-color: #2980b9;
}
.error-message {
color: #e74c3c;
font-size: 0.9rem;
margin-top: 0.25rem;
}
.success-message {
background-color: #d4edda;
color: #155724;
padding: 1rem;
border-radius: 4px;
margin-bottom: 1rem;
}
Code language: CSS (css)
セキュリティ&スパム対策
お問い合わせフォームは外部からの入力を受け取るため、セキュリティ対策は必須です。
reCAPTCHA(CF7/WPFormsの設定ポイント)
Contact Form 7での設定:
- Google reCAPTCHAでサイト登録
- サイトキーとシークレットキーを取得
- CF7→インテグレーション→reCAPTCHAに設定
- フォームに
[recaptcha]
タグを追加
WPFormsでの設定:
- WPForms→設定→reCAPTCHA
- サイトキーとシークレットキーを入力
- フォーム編集画面でreCAPTCHAフィールドを追加
v3とv2の選び方:
- v3: ユーザー操作不要、スコアベースで判定
- v2: クリックまたは画像選択が必要、確実性が高い
CSRF対策(Nonce)/Honeypot/日本語入力チェックの考え方
Nonce(ナンス):
// フォーム生成時
wp_nonce_field('contact_form_nonce', 'contact_nonce');
// 検証時
if (!wp_verify_nonce($_POST['contact_nonce'], 'contact_form_nonce')) {
wp_die('不正なリクエストです。');
}
Code language: PHP (php)
Honeypot(ハニーポット):
<!-- 人間には見えないが、ボットが入力してしまうフィールド -->
<input type="text" name="website" style="display:none;" tabindex="-1" autocomplete="off">
Code language: HTML, XML (xml)
日本語入力チェック:
function contains_japanese($text) {
return preg_match('/[\x{3040}-\x{309F}\x{30A0}-\x{30FF}\x{4E00}-\x{9FAF}]/u', $text);
}
if (!contains_japanese($message)) {
$errors[] = 'メッセージは日本語で入力してください。';
}
Code language: PHP (php)
実務で効くカスタマイズ
基本的なフォームから一歩進んで、実務で役立つ機能を追加しましょう。
自動返信メール(送信者控え/ヘッダー設定)
HTMLメール対応:
function send_html_auto_reply($email, $name, $subject, $message) {
$to = $email;
$mail_subject = 'お問い合わせを受け付けました - ' . get_bloginfo('name');
$html_message = '
<html>
<body>
<h2>' . $name . '様</h2>
<p>お問い合わせいただき、ありがとうございます。</p>
<p>以下の内容で受け付けいたしました。</p>
<table border="1" cellpadding="10">
<tr><th>お名前</th><td>' . esc_html($name) . '</td></tr>
<tr><th>件名</th><td>' . esc_html($subject) . '</td></tr>
<tr><th>メッセージ</th><td>' . nl2br(esc_html($message)) . '</td></tr>
</table>
<p>担当者より2営業日以内にご連絡いたします。</p>
</body>
</html>
';
$headers = array(
'Content-Type: text/html; charset=UTF-8',
'From: ' . get_bloginfo('name') . ' <noreply@' . parse_url(home_url(), PHP_URL_HOST) . '>'
);
wp_mail($to, $mail_subject, $html_message, $headers);
}
Code language: HTML, XML (xml)
ファイル添付(MIME・容量・保存場所)
安全なファイルアップロード:
function handle_file_upload() {
if (!isset($_FILES['attachment']) || $_FILES['attachment']['error'] !== UPLOAD_ERR_OK) {
return false;
}
$file = $_FILES['attachment'];
// ファイルサイズチェック(5MB以下)
if ($file['size'] > 5 * 1024 * 1024) {
return new WP_Error('file_too_large', 'ファイルサイズは5MB以下にしてください。');
}
// MIMEタイプチェック
$allowed_types = array('image/jpeg', 'image/png', 'application/pdf', 'text/plain');
$file_type = wp_check_filetype_and_ext($file['tmp_name'], $file['name']);
if (!in_array($file_type['type'], $allowed_types)) {
return new WP_Error('invalid_file_type', '許可されていないファイル形式です。');
}
// WordPressのアップロード処理
if (!function_exists('wp_handle_upload')) {
require_once(ABSPATH . 'wp-admin/includes/file.php');
}
$upload_overrides = array('test_form' => false);
$movefile = wp_handle_upload($file, $upload_overrides);
if ($movefile && !isset($movefile['error'])) {
return $movefile['url'];
} else {
return new WP_Error('upload_failed', $movefile['error']);
}
}
Code language: PHP (php)
送信データの保存(Flamingo or カスタム投稿タイプ)
カスタム投稿タイプでの保存:
function save_contact_data($name, $email, $subject, $message) {
$post_data = array(
'post_title' => $subject . ' - ' . $name,
'post_content' => $message,
'post_status' => 'private',
'post_type' => 'contact_submission',
'meta_input' => array(
'contact_name' => $name,
'contact_email' => $email,
'contact_subject' => $subject,
'submission_date' => current_time('mysql'),
'user_ip' => $_SERVER['REMOTE_ADDR'] ?? '',
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? ''
)
);
return wp_insert_post($post_data);
}
// カスタム投稿タイプを登録
function register_contact_post_type() {
register_post_type('contact_submission', array(
'label' => 'お問い合わせ',
'public' => false,
'show_ui' => true,
'show_in_menu' => true,
'supports' => array('title', 'editor'),
'capabilities' => array(
'create_posts' => 'do_not_allow'
),
'map_meta_cap' => true
));
}
add_action('init', 'register_contact_post_type');
Code language: PHP (php)
トラブルシューティング(症状→原因→直し方)
よくある問題と解決方法を症状別にまとめました。
メールが届かない
症状: フォーム送信後、管理者にメールが届かない
考えられる原因と対処法:
- サーバーのメール機能が無効
- 解決策: SMTPプラグイン(WP Mail SMTP)を導入
- Gmail、Outlook等の外部SMTPサービスを利用
- スパムフィルターに引っかかっている
- 解決策: SPF、DKIM、DMARCレコードをDNSに設定
- 送信者アドレスをサイトドメインと一致させる
- wp_mail()が正しく動作していない
- 確認方法:
wp_mail()
の戻り値をチェック
$sent = wp_mail($to, $subject, $message); if (!$sent) { error_log('メール送信に失敗しました'); }
- 確認方法:
送信できない(フォームが動作しない)
症状: 送信ボタンを押してもページが動かない、エラーが出る
考えられる原因と対処法:
- JavaScriptエラー
- 確認方法: ブラウザの開発者ツールでコンソールをチェック
- 解決策: プラグインの競合を確認、テーマを一時的にデフォルトに変更
- PHPエラー
- 確認方法: WordPressデバッグログを確認
// wp-config.phpに追加 define('WP_DEBUG', true); define('WP_DEBUG_LOG', true);
- サーバーのリソース不足
- 解決策: メモリ制限を増やす、実行時間を延長する
reCAPTCHAが動かない
症状: reCAPTCHAが表示されない、または認証に失敗する
考えられる原因と対処法:
- APIキーの設定ミス
- 確認項目: サイトキーとシークレットキーが正しく入力されているか
- ドメインが正しく登録されているか
- HTTPSの問題
- 解決策: サイト全体をHTTPS化する
- WordPressの設定でサイトURLをhttps://に変更
- キャッシュプラグインの影響
- 解決策: reCAPTCHA部分をキャッシュ対象から除外
403エラー(Nonce検証失敗)
症状: フォーム送信時に403エラーまたは「不正なリクエスト」と表示
考えられる原因と対処法:
- Nonceの有効期限切れ
- 解決策: ページのキャッシュ時間を短縮、Ajax更新でNonceを再取得
- セキュリティプラグインの誤作動
- 確認項目: Wordfence、SiteGuard等の設定を確認
- 解決策: フォームURLをホワイトリストに追加
- サーバーレベルのセキュリティ
- 解決策: .htaccessやmod_securityの設定を確認
ファイルが弾かれる
症状: 添付ファイルがアップロードできない
考えられる原因と対処法:
- ファイルサイズ制限
- 確認方法:
phpinfo()
でupload_max_filesize、post_max_sizeをチェック - 解決策: php.iniまたは.htaccessで制限値を変更
- 確認方法:
- MIME タイプ制限
- 解決策: WordPressのアップロード可能ファイル形式を拡張
function allow_additional_file_types($mimes) { $mimes['pdf'] = 'application/pdf'; return $mimes; } add_filter('upload_mimes', 'allow_additional_file_types');
- ディレクトリの権限不足
- 確認項目: wp-content/uploadsディレクトリの権限(755または775)
- 解決策: FTPまたはサーバー管理画面から権限を変更
仕上げチェックリスト
フォーム設置後、以下の項目を確認して完成度を高めましょう。
機能チェック
- [ ] フォーム送信が正常に動作する
- [ ] 必須項目の入力チェックが機能している
- [ ] 管理者に通知メールが届く
- [ ] 自動返信メールが送信者に届く
- [ ] エラーメッセージが適切に表示される
- [ ] 送信完了メッセージが表示される
- [ ] ファイル添付機能(使用する場合)が正常動作
表示チェック
- [ ] PC・タブレット・スマホで正しく表示される
- [ ] フォームのデザインがサイトに馴染んでいる
- [ ] 入力フィールドが使いやすい
- [ ] エラーメッセージが見やすい位置に表示
- [ ] 必須項目が明確に示されている
- [ ] フォーカス時のスタイルが適用されている
セキュリティチェック
- [ ] Nonce検証が実装されている
- [ ] 入力データのサニタイズが行われている
- [ ] SQLインジェクション対策済み
- [ ] CSRF対策済み
- [ ] スパム対策(reCAPTCHA/Honeypot)が有効
- [ ] ファイルアップロード時の検証が実装されている
- [ ] XSS対策でデータ出力時にエスケープ処理
速度・パフォーマンス
- [ ] フォーム読み込み時間が適切(3秒以内)
- [ ] JavaScriptファイルサイズが最適化されている
- [ ] 不要なCSSが読み込まれていない
- [ ] 画像ファイルが最適化されている
- [ ] キャッシュプラグインとの競合がない
ログ・分析
- [ ] 送信データの保存設定が完了している
- [ ] エラーログの設定が有効
- [ ] Google Analyticsでフォーム送信を追跡設定
- [ ] 送信率の計測方法が確立されている
バックアップ・復旧
- [ ] フォーム設定のバックアップが取られている
- [ ] 送信データのバックアップ設定が完了
- [ ] 復旧手順が文書化されている
- [ ] 定期的なバックアップスケジュールが設定済み
まとめ(今日できる次の一歩)
WordPressのお問い合わせフォームは、サイトの信頼性を高め、訪問者との重要なコミュニケーション手段となります。この記事で紹介した内容を参考に、あなたのサイトに最適なフォームを実装してください。
今日から始められる具体的なアクション:
初心者の方:
- Contact Form 7をインストールして基本フォームを作成
- Flamingoで送信データの保存設定
- reCAPTCHA v3の導入でスパム対策
中級者の方:
- 自作フォームでサイトの読み込み速度向上
- 自動返信メールのHTMLメール化
- カスタム投稿タイプでのデータ管理システム構築
上級者の方:
- 高度なバリデーション機能の実装
- 外部CRMシステムとの API 連携
- A/Bテストによる送信率最適化
お問い合わせフォームは一度設置して終わりではありません。定期的な動作確認、セキュリティアップデート、ユーザビリティの改善を継続的に行い、訪問者にとって使いやすく、管理者にとって運用しやすいフォームを維持していきましょう。
何か不明な点があれば、WordPressコミュニティやサポートフォーラムを活用し、常に最新の情報をキャッチアップしながらフォーム運用のスキルを向上させていってください。