PHPフォームのHTML作成

お問い合わせの最初のページ

最初の段階のHTMLでは、セキュリティを意識した基本マークアップを入れておきます(ハニーポットでスパム対策を行います)。
この回は HTMLのみ の実装で、見た目の調整は次回(php-contact02)でCSSを追加します。

また、フォームのHTMLには 「入力しやすさ(UX)」を高めるための工夫 が欠かせません。

  • label要素で入力欄と見出しをしっかり関連付ける
    → クリックでフォーカスでき、アクセシビリティにも良い
  • autocomplete属性を適切に指定する
    → 名前・電話番号・メールアドレスなど、ブラウザが候補を出しやすくなり、入力のストレスが減る
  • 必須項目の明示(*やrequired属性など)
    → どこを入力すべきかが一目でわかる

こうした“基本マークアップの質”が高いと、CSSで見た目を整える前の段階でもすでに 「入力しやすいフォーム」 を作ることができます。

フォルダとファイルの準備

  1. 任意の作業ディレクトリに php-contact/ フォルダを作成
  2. その中に form.php を新規作成
  3. 次回用に style.css(空でOK)も用意しておくとスムーズです

※ ローカルのXAMPP環境などで動かす場合は、htdocs/php-contact/ のように配置します。

form.php(HTMLのみ)コード

まずはHTMLを書いてみよう。下記のコードを入力してブラウザで開いてみましょう。

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>お問い合わせフォーム</title>
    <meta name="description" content="お問い合わせフォーム">
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <main class="container">
        <h1>お問い合わせフォーム</h1>

        <form id="contactForm" action="confirm.php" method="post" autocomplete="on">

            <!-- スパム対策(ハニーポット)ここはCSSで必ず非表示にします。 -->
            <div class="hp-wrap" style="display:none;">
                <label for="company">会社名(空のままにしてください)</label>
                <input type="text" id="company" name="company" autocomplete="organization">
            </div>


            <div class="form-row">
                <label for="name">氏名<span class="required">*</span></label>
                <input type="text" id="name" name="name" autocomplete="name">
            </div>

            <div class="form-row">
                <label for="tel">電話番号</label>
                <input type="tel" id="tel" name="tel" autocomplete="tel" placeholder="例)090-1234-5678">
            </div>

            <div class="form-row">
                <label for="email">メールアドレス<span class="required">*</span></label>
                <input type="email" id="email" name="email" autocomplete="email">
            </div>

            <div class="form-row">
                <fieldset>
                    <legend>性別</legend>
                    <label><input type="radio" name="gender" value="男性"> 男性</label>
                    <label><input type="radio" name="gender" value="女性"> 女性</label>
                    <label><input type="radio" name="gender" value="無回答" checked> 無回答</label>
                </fieldset>
            </div>

            <div class="form-row">
                <label for="message">お問い合わせ内容<span class="required">*</span></label>
                <textarea id="message" name="message" rows="8"></textarea>
            </div>

            <div class="form-row">
                <label>
                    <input type="checkbox" name="agree" value="1">
                    個人情報の取り扱いに同意します<span class="required">*</span>
                </label>
            </div>

            <div class="actions">
                <button type="submit">確認する</button>
            </div>
        </form>
    </main>
</body>

</html>

ハニーポットの設置

ハニーポットは、スパムボット対策の手法のひとつです。人間のユーザーには見えない入力欄(CSSで非表示設定)を設置しておくことで、そのnameのキー(値)に入力があったら、見えないはずの場所に入力してきたことでスパム判定となります。

スパムボットはフォーム内のすべての入力欄に値を入れることが多いため、この「見えないはずの欄に何か入っていたらそれは、スパムだ」ということができます。

            <!-- スパム対策(ハニーポット)ここはCSSで必ず非表示にします。 -->
            <div class="hp-wrap" style="display:none;">
                <label for="company">会社名(空のままにしてください)</label>
                <input type="text" id="company" name="company" autocomplete="organization">
            </div>

action="confirm.php"(送信先:確認画面)

  • フォーム送信後、すぐにメール送信せず、一度確認画面を挟むことで、入力ミスや二重送信を防ぎます。(RPG)
  • 典型的なフロー
form.php → confirm.php(サーバー側バリデーション)
         → send.php(メール送信)
         → thanks.php(完了ページ)

PRGパターンとは?send.php で送信後に thanks.php にリダイレクトすることで、
「ページを再読み込みしたらメールがまた送られた!」という二重送信事故を防ぎます。

<label> タグ

属性説明
<label for="name">氏名</label>入力欄にラベル(見出し)をつけるタグ。for属性で関連する入力欄のidと紐づけます。
for="name"同じ値を持つidを探し、その入力欄にラベルを対応させます。ラベルをクリックすると入力欄がフォーカスされるようになります。

アクセシビリティ(音声読み上げなど)にも重要な役割を持つタグです。

<input> タグと type 属性

フォーム入力欄を作るための最も基本的なタグです。type属性の値によって入力の種類やブラウザのチェック動作が変わります。

type属性用途補足
text文字入力欄(氏名・住所など)自由入力欄として最も一般的
tel電話番号入力欄スマホでは数字キーボードが表示されます
emailメールアドレス入力欄送信時に「@」など形式チェックが自動で行われます
passwordパスワード入力欄入力文字が伏せ字(●)で表示されます
radio単一選択(性別など)同じname属性を持つ項目の中から1つだけ選択可能
checkbox複数選択・同意チェックなど1つまたは複数を選べます
submit送信ボタン<button type="submit"> でも同様に送信できます

required(入力必須の指定)

required 属性を付けると、入力欄が空のまま送信されるのを防ぐことができます。
ブラウザが自動でチェックを行い、未入力のときは送信前にエラーメッセージが表示されます。

<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<input type="checkbox" name="agree" value="1" required>

このように指定することで、送信前の基本的な入力漏れをブラウザ側で防止できます。
ただし、JavaScriptを無効化したり、HTMLを改ざんしたりすると、このチェックを回避できてしまうため、サーバー側(例:confirm.php など)でも必ず再チェックを行う必要があります。

required はユーザー体験を向上させる便利な属性ですが、完全なセキュリティ対策にはなりません。

autocomplete(入力補完の精度を上げる)

ブラウザに「この入力欄は氏名/メールアドレス/電話番号の入力欄です」と伝えることで、ユーザーが過去に入力した正しい候補(オートコンプリート)を自動で表示させることができます。入力ミスを防ぎ、入力の手間を減らすために活用します。

<input type="text"  name="name"  autocomplete="name">
<input type="email" name="email" autocomplete="email">
<input type="tel"   name="tel"   autocomplete="tel">

ブラウザやスマートフォンの自動入力機能と連動するため、正しいトークン(name / email / tel など)を指定すると候補精度が高まります。

一方で、セキュリティ上自動入力を避けたいフォーム(パスワードや検索欄など)では、次のように autocomplete="off" を指定して候補を非表示にします。

<input type="password" name="password" autocomplete="off">

MDN HTML 属性: autocomplete >>>> https://developer.mozilla.org/ja/docs/Web/HTML/Reference/Attributes/autocomplete

よく使うトークン

入力欄値(トークン)
氏名name<input autocomplete="name">
メールemail<input autocomplete="email">
電話番号tel<input autocomplete="tel">
郵便番号postal-code<input autocomplete="postal-code">
パスワード(既存)current-password<input autocomplete="current-password">
パスワード(新規)new-password<input autocomplete="new-password">

4) fieldset + legend(グループ化とアクセシビリティ)

  • 関連する入力(今回なら「性別」)を意味的にグループ化するタグです。
  • スクリーンリーダーなどで「この選択肢は何に関するものか」が分かりやすくなり、アクセシビリティ向上につながります。
<fieldset>
  <legend>性別<span class="required">*</span></legend>
  <label><input type="radio" name="gender" value="男性" required> 男性</label>
  <label><input type="radio" name="gender" value="女性"> 女性</label>
  <label><input type="radio" name="gender" value="無回答"> 無回答</label>
</fieldset>
吹き出し
WebTraining AI
WebTraining AI へようこそ!
HTML / CSS / JavaScript / Wordpress/ PHP など、 コードやプログラミングについて何でも質問できます。