21
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHPでフォームを作成する基本

Last updated at Posted at 2020-02-04

##フォームの基本

  • 入力画面
  • 確認画面
  • 完了画面

index.php → confirm.php → thanks.php
と作る場合が多い

その場合、formのaction属性をそれぞれの飛び先に指定する

##入力フォーム



    <form method="post" action=""> <?php //送信先が空なので、自分自身(index.php)を再度呼び出す
                                    ?>
      <div class="element_wrap">
        <label>氏名</label>
        <input type="text" name="your_name" value="<?php if (!empty($_POST['your_name'])) {
                                                      echo $_POST['your_name'];
                                                    } ?>">
        <!-- POSTパラメータが空じゃない場合のみvalue属性にセット -->
      </div>
      <div class="element_wrap">
        <label>メールアドレス</label>
        <input type="mail" name="email" value="<?php if (!empty($_POST['email'])) {
                                                  echo $_POST['email'];
                                                } ?>">
      </div>
      <div class="element_wrap">
        <label>性別</label>
        <label for="gender_male"><input id="gender_male" type="radio" name="gender" value="male">男性</label>
        <label for="gender_female"><input id="gender_female" type="radio" name="gender" value="female">女性</label>
      </div>
      <div class="element_wrap">
        <label>年齢</label>
        <select name="age">
          <option value="">選択してください</option>
          <option value="1">〜19歳</option>
          <option value="2">20歳〜29歳</option>
          <option value="3">30歳〜39歳</option>
          <option value="4">40歳〜49歳</option>
          <option value="5">50歳〜59歳</option>
          <option value="6">60歳〜</option>
        </select>
      </div>
      <div class="element_wrap">
        <label>お問い合わせ内容</label>
        <textarea name="contact"></textarea>
      </div>
      <div class="element_wrap">
        <label for="agreement"><input id="agreement" type="checkbox" name="agreement" value="1">プライバシーポリシーに同意する</label>
      </div>
      <input type="submit" name="btn_confirm" value="入力内容を確認する">
    </form>


##確認ページ



    <form method="post" action="">
      <div class="element_wrap">
        <label>氏名</label>
        <p><?php echo $_POST['your_name']; ?></p>
      </div>
      <div class="element_wrap">
        <label>メールアドレス</label>
        <p><?php echo $_POST['email']; ?></p>
      </div>
      <div class="element_wrap">
        <label>性別</label>
        <p><?php if($_POST['gender'] === "male" ){ echo '男性'; } else {echo '女性' ; }?></p>
      </div>
      <div class="element_wrap">
        <label>年齢</label>
        <p>
          <?php if( $_POST['age'] === "1") {
            echo '〜19歳';
          }elseif($_POST['age'] === "2") {
            echo '20歳〜29歳';
            }elseif($_POST['age'] === "3") {
            echo '30歳〜39歳';
            }elseif($_POST['age'] === "4"){
            echo '40歳〜49歳';
            }elseif($_POST['age'] === "5"){
            echo '50歳〜59歳';
            }elseif($_POST['age'] === "6"){
            echo '60歳〜';
            }
          ?>
        </p>
      </div>
      <div class="element_wrap">
        <label>お問い合わせ内容</label>
        <p><?php echo nl2br($_POST['contact']); ?></p>
      </div>
      <div class="element_wrap">
        <p>
          <?php
          if($_POST['agreement'] === "1") {
            echo '同意する';
          } else {
            echo '同意しない';
          }
          ?>
        </p>
      </div>
      <!-- 入力値の受け渡し用 -->
      <input type="submit" name="btn_back" value="戻る">
      <input type="submit" name="btn_submit" value="送信">
      <input type="hidden" name="your_name" value="<?php echo $_POST['your_name']; ?>">
      <input type="hidden" name="email" value="<?php echo $_POST['email']; ?>">
      <input type="hidden" name="gender" value="<?php echo $_POST['gender']; ?>">
      <input type="hidden" name="age" value="<?php echo $_POST['age']; ?>">
      <input type="hidden" name="contact" value="<?php echo $_POST['contact']; ?>">
      <input type="hidden" name="agreement" value="<?php echo $_POST['agreement']; ?>">
    </form>

##ページの切り替え

    <form method="post" action=""> <?php //送信先が空なので、自分自身(index.php)を再度呼び出す

formがこうなっているので、自分自身を再び呼び出している。

そのため、別ファイルに記述するのではなく、同じファイルに全ての内容を記述していく。

(ただし、action="confirm.php"とした場合は、しっかり別ファイルが必要になるので注意)

##ページの切り替え方法



/*---------------------------------------
    ページ切り替え
-----------------------------------------*/

$page_flag = 0;

if (!empty($_POST['btn_confirm'])) {
  //$_POST[‘btn_confirm’]の値が渡されているか確認
  $page_flag  = 1;
} elseif (!empty($_POST['btn_submit'])) {
  //$_POST[‘btn_submit’]の値が渡されているか確認
  $page_flag = 2;
}
//入力ページや確認ページの表示をスイッチするフラグになる
//$_POST[‘btn_confirm’]があれば、確認ページへ進む

//[0]入力
//[1]確認
//[2]完了

どのボタンが押されたかによって、フラグを立て、
条件分岐させている

例えば、

<input type="submit" name="btn_confirm" value="入力内容を確認する">

コレだと、$_POST['btn_submit']が送信されるため、$page_flagには1が入る。

フォーム記載欄に、下記のように条件分岐させればオッケー。


  <?php if ($page_flag === 1) : //確認ページの内容 ?>

  <?php elseif ($page_flag === 2) : //完了ページの内容 ?>

    <p>送信が完了しました</p>

  <?php else : //入力ページの内容 ?>

  <?php endif; ?>


##メール送信機能



/*---------------------------------------
    メール送信機能

// 変数の設定
$to = "testtaro@gray-code.com";
$subject = "メール送信のテスト";
$text = "メール本文です。";

// メール送信
mb_send_mail( $to, $subject, $text);
-----------------------------------------*/

//変数とタイムゾーン
$header = null; //メールの件名に入る文字列
$auto_reply_subject = null;
$auto_reply_text = null;
date_default_timezone_set('Asia/Tokyo');

// ヘッダー情報を設定
$header = "MIME-Version: 1.0\n";
$header .= "From: GRAYCODE <noreply@gray-code.com>\n";
$header .= "Reply-To: GRAYCODE <noreply@gray-code.com>\n";

//件名を設定
$auto_reply_subject = 'お問い合わせありがとうございます';

//本文設定
$auto_reply_text = "この度はお問い合わせありがとうございます。下記の内容でお問い合わせを受け付けました。\n\n";
$auto_reply_text .= "お問い合わせ日時:" . date("Y-m-d H:i") . "\n";
$auto_reply_text .= "氏名:" . $_POST['your_name'] . "\n";
$auto_reply_text .= "メールアドレス:" . $_POST['email'] . "\n\n";
$auto_reply_text .= "CODE株式会社";

//メール送信
mb_send_mail($_POST['email'], $auto_reply_subject, $auto_reply_text);


/**--------運営者側へ送るメール */

// 運営側へ送るメールの件名
$admin_reply_subject = "お問い合わせを受け付けました";

// 本文を設定
$admin_reply_text = "下記の内容でお問い合わせがありました。\n\n";
$admin_reply_text .= "お問い合わせ日時:" . date("Y-m-d H:i") . "\n";
$admin_reply_text .= "氏名:" . $_POST['your_name'] . "\n";
$admin_reply_text .= "メールアドレス:" . $_POST['email'] . "\n\n";

// 運営側へメール送信
mb_send_mail('webmaster@gray-code.com', $admin_reply_subject, $admin_reply_text, $header);


?>

##入力値のサニタイズ
セキュリティ対策の一つ「入力値のサニタイズ」

フォームにHTMLやJSなどのプログラミングコードを入力しても実行されてないようにする。

→無効化したテキストデータにする

hemlspecialchars($string,$flags,$encodinf,$h_flag)

  • $string 対象となる文字列
  • $flags エンコードのフラグ
  • $encodinf 文字コード
    -$h_flag HTMl変換フラグ

HTMLエンティティへ変換し、無効化することができる。
(HTMLエンティティとは、文字列の素の姿)

htmlspecialchars

###フォームにサニタイズを実装する

$clean = array();

//サニタイズ
if (!empty($_POST)) {
  foreach ($_POST as $key => $value) {
    $clean[$key] = htmlspecialchars($value, ENT_QUOTES);
  }
}

POSTパラメータが存在するかを判断、
そもそもPOSTがなかったら、サニタイズも必要ないので、ifで条件分岐させる

foreachでPOSTパラメータを配列ごと渡して、入力値を1つずつ取り出してサニタイズする。
その後、値を$cleanに格納

サニタイズされた入力値は$cleanに入っているので、$cleanの配列から値を取り出すように変更すればOK

##バリデーション

  • 氏名 – 未入力チェック、文字の長さチェック
  • メールアドレス – 未入力チェック、形式チェック
  • 性別 – 未入力チェック、形式チェック
  • 年齢 – 未入力チェック、形式チェック
  • お問い合わせ内容 – 未入力チェック
  • プライバシーポリシーに同意 – 未入力チェック、形式チェック

さらに、「未入力チェック」は全項目に用意する

###未入力チェック


$error = array();

if (!empty($clean['btn_confirm'])) {
  //$_POST[‘btn_confirm’]の値が渡されているか確認

  $error = validation($clean);

  if( empty($error)) {
    $page_flag  = 1;
  }


function validation($data) {
  $error = array();

  //氏名のバリデーション
  if( empty($data['your_name'])) {
    $error[] = "氏名は必ず入力して下さい";
  }
  return $error;
}

バリデーション用にvalidation関数を用意
関数の返り血でエラーが合ったかどうかを判断する。

empty関数で、入力がない場合、$errorへメッセージを追加

  $error = validation($clean);

  if( empty($error)) {
    $page_flag  = 1;
  }

エラーが見つからない場合は、$page_flagに1を設定し、ページを確認ページに切り替える

###エラーメッセージの表示


  <?php if (!empty($error)) { ?>
  <ul class="error_list">
    <?php foreach ($error as $value) : ?>
    <li><?php echo $value; ?></li>
    <?php endforeach; ?>
  </ul>
  <?php } ?>

ここはもう簡単で、
emptyで$errorがあるかを判断して出力するだけ。

$errorは配列なので、foreachでループして出力する

###入力値の長さ(文字数)を調べる

  if (empty($data['your_name'])) {
    $error[] = "氏名は必ず入力して下さい";
  } elseif( 20 < mb_strlen($data['your_name'])) {
    $error[] = "指名は20文字以内で入力して下さい";
  }

mb_strlenは、引数で渡した文字列の長さを返す

###アドレスの形式を調べる


  if (empty($data['email'])) {
    $error[] = "メールアドレスは必ず入力して下さい";
  } elseif( !preg_match( '/^[0-9a-z_.\/?]+@([0-9a-z-]+\.)+[0-9a-z-]+$/',$data['email'])) {
    $error[] = "メールアドレスは正しい形式で入力して下さい";
  }

メールアドレス正規表現

###特定の値が入力されているかを調べる


  if (empty($data['gender'])) {
    $error[] = "性別は必ず入力して下さい";
  } elseif( $data['gender'] !== 'male' && $data['gender'] !=='female') {
    $error[] = "性別は必ず入力して下さい";
  }

ラジオボタンなど、いずれかの入力が必須の場合

###特定の範囲が入力されているか調べる

// 年齢のバリデーション
if( empty($data['age']) ) {
	$error[] = "「年齢」は必ず入力してください。";

} elseif( (int)$data['age'] < 1 || 6 < (int)$data['age'] ) {
	$error[] = "「年齢」は必ず入力してください。";
}

セレクトボックスなど、

value属性の値が1より小さい(0以下)、または6より大きい(7以上)の場合にエラーと判断しています。

###チェックボックスのチェックを調べる

  if (empty($data['agreement'])) {
    $error[] = "プライバシーポリシーを確認して下さい";
  } elseif ((int) $data['agreement'] !== 1) {
    $error[] = "プライバシーポリシーをご確認ください。";
  }

##セッションを作る

// セッションの書き込み
session_start();
$_SESSION['page'] = true;

確認ページ

session_start()でセッション開始の合図を出し、$_SESSION[‘page’]に「true」を格納

完了ページ

	session_start();
	if( !empty($_SESSION['page']) && $_SESSION['page'] === true ) {

		// セッションの削除
		unset($_SESSION['page']);

//$_SESSION['page']が空じゃない時のみ、完了ページの処理を実行する


	} else {
		$page_flag = 0;
	}

<?php
// var_dump($_POST);


//変数の初期化

/*---------------------------------------
    ページ切り替え
-----------------------------------------*/

$page_flag = 0;
$clean = array();
$error = array();

//サニタイズ
if (!empty($_POST)) {
  foreach ($_POST as $key => $value) {
    $clean[$key] = htmlspecialchars($value, ENT_QUOTES);
  }
}


if (!empty($clean['btn_confirm'])) {
  //$_POST[‘btn_confirm’]の値が渡されているか確認

  $error = validation($clean);

  if (empty($error)) { //エラーがなかった時、確認ページへ
    $page_flag  = 1;

    // セッションの書き込み
    session_start();
    $_SESSION['page'] = true;
  }
} elseif (!empty($clean['btn_submit'])) {
  //$_POST[‘btn_submit’]の値が渡されているか確認
  $page_flag = 2;
}
//入力ページや確認ページの表示をスイッチするフラグになる
//$_POST[‘btn_confirm’]があれば、確認ページへ進む

//[0]入力
//[1]確認
//[2]完了


session_start();
if (!empty($_SESSION['page']) && $_SESSION['page'] === true) {

  // セッションの削除
  unset($_SESSION['page']);



  /*---------------------------------------
    メール送信機能

// 変数の設定
$to = "testtaro@gray-code.com";
$subject = "メール送信のテスト";
$text = "メール本文です。";

// メール送信
mb_send_mail( $to, $subject, $text);
-----------------------------------------*/

  //変数とタイムゾーン
  $header = null; //メールの件名に入る文字列
  $auto_reply_subject = null;
  $auto_reply_text = null;
  date_default_timezone_set('Asia/Tokyo');

  // ヘッダー情報を設定
  $header = "MIME-Version: 1.0\n";
  $header .= "From: GRAYCODE <noreply@gray-code.com>\n";
  $header .= "Reply-To: GRAYCODE <noreply@gray-code.com>\n";

  //件名を設定
  $auto_reply_subject = 'お問い合わせありがとうございます';

  //本文設定
  $auto_reply_text = "この度はお問い合わせありがとうございます。下記の内容でお問い合わせを受け付けました。\n\n";
  $auto_reply_text .= "お問い合わせ日時:" . date("Y-m-d H:i") . "\n";
  $auto_reply_text .= "氏名:" . $clean['your_name'] . "\n";
  $auto_reply_text .= "メールアドレス:" . $clean['email'] . "\n\n";
  $auto_reply_text .= "CODE株式会社";

  //メール送信
  mb_send_mail($clean['email'], $auto_reply_subject, $auto_reply_text);


  /**--------運営者側へ送るメール */

  // 運営側へ送るメールの件名
  $admin_reply_subject = "お問い合わせを受け付けました";

  // 本文を設定
  $admin_reply_text = "下記の内容でお問い合わせがありました。\n\n";
  $admin_reply_text .= "お問い合わせ日時:" . date("Y-m-d H:i") . "\n";
  $admin_reply_text .= "氏名:" . $clean['your_name'] . "\n";
  $admin_reply_text .= "メールアドレス:" . $clean['email'] . "\n\n";

  // 運営側へメール送信
  mb_send_mail('webmaster@gray-code.com', $admin_reply_subject, $admin_reply_text, $header);
} else {
  $page_flag = 0;
}


function validation($data)
{
  $error = array();

  //氏名のバリデーション
  if (empty($data['your_name'])) {
    $error[] = "氏名は必ず入力して下さい";
  } elseif (20 < mb_strlen($data['your_name'])) {
    $error[] = "指名は20文字以内で入力して下さい";
  }


  if (empty($data['email'])) {
    $error[] = "メールアドレスは必ず入力して下さい";
  } elseif (!preg_match('/^[0-9a-z_.\/?]+@([0-9a-z-]+\.)+[0-9a-z-]+$/', $data['email'])) {
    $error[] = "メールアドレスは正しい形式で入力して下さい";
  }


  if (empty($data['gender'])) {
    $error[] = "性別は必ず入力して下さい";
  } elseif ($data['gender'] !== 'male' && $data['gender'] !== 'female') {
    $error[] = "性別は必ず入力して下さい";
  }


  if (empty($data['age'])) {
    $error[] = "年齢は必ず入力して下さい";
  } elseif ((int) $data['age'] < 1 || 6 < (int) $data['age']) {
    $error[] = "年齢は必ず入力して下さい";
  }

  if (empty($data['contact'])) {
    $error[] = "お問い合わせ内容は必ず入力して下さい";
  }

  if (empty($data['agreement'])) {
    $error[] = "プライバシーポリシーを確認して下さい";
  } elseif ((int) $data['agreement'] !== 1) {
    $error[] = "プライバシーポリシーをご確認ください。";
  }


  return $error;
}

?>

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

<head>
  <title>お問い合わせフォーム</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <h1>お問い合わせフォーム</h1>

  <?php if ($page_flag === 1) : //  ----------------確認ページの内容-----------------------
  ?>

  <form method="post" action="">
    <div class="element_wrap">
      <label>氏名</label>
      <p><?php echo $clean['your_name']; ?></p>
    </div>
    <div class="element_wrap">
      <label>メールアドレス</label>
      <p><?php echo $clean['email']; ?></p>
    </div>
    <div class="element_wrap">
      <label>性別</label>
      <p><?php if ($clean['gender'] === "male") {
              echo '男性';
            } else {
              echo '女性';
            } ?></p>
    </div>
    <div class="element_wrap">
      <label>年齢</label>
      <p>
          <?php if ($clean['age'] === "1") {
            echo '〜19歳';
          } elseif ($clean['age'] === "2") {
            echo '20歳〜29歳';
          } elseif ($clean['age'] === "3") {
            echo '30歳〜39歳';
          } elseif ($clean['age'] === "4") {
            echo '40歳〜49歳';
          } elseif ($clean['age'] === "5") {
            echo '50歳〜59歳';
          } elseif ($clean['age'] === "6") {
            echo '60歳〜';
          }
          ?>
        </p>
    </div>
    <div class="element_wrap">
      <label>お問い合わせ内容</label>
      <p><?php echo nl2br($clean['contact']); ?></p>
    </div>
    <div class="element_wrap">
      <p>
          <?php
          if ($clean['agreement'] === "1") {
            echo '同意する';
          } else {
            echo '同意しない';
          }
          ?>
        </p>
    </div>
    <!-- 入力値の受け渡し用 -->
    <input type="submit" name="btn_back" value="戻る">
    <input type="submit" name="btn_submit" value="送信">
    <input type="hidden" name="your_name" value="<?php echo $clean['your_name']; ?>">
    <input type="hidden" name="email" value="<?php echo $clean['email']; ?>">
    <input type="hidden" name="gender" value="<?php echo $clean['gender']; ?>">
    <input type="hidden" name="age" value="<?php echo $clean['age']; ?>">
    <input type="hidden" name="contact" value="<?php echo $clean['contact']; ?>">
    <input type="hidden" name="agreement" value="<?php echo $clean['agreement']; ?>">
  </form>

  <?php elseif ($page_flag === 2) : // ----------------完了ページの内容-----------------------
  ?>

  <p>送信が完了しました</p>

  <?php else : //----------------入力ページの内容-----------------------
  ?>

  <?php if (!empty($error)) { ?>
  <ul class="error_list">
    <?php foreach ($error as $value) : ?>
    <li><?php echo $value; ?></li>
    <?php endforeach; ?>
  </ul>
  <?php } ?>

  <form method="post" action=""> <?php //送信先が空なので、自分自身(index.php)を再度呼び出す
                                    ?>
    <div class="element_wrap">
      <label>氏名</label>
      <input type="text" name="your_name" value="<?php if (!empty($clean['your_name'])) {
                                                      echo $clean['your_name'];
                                                    } ?>">
      <!-- POSTパラメータが空じゃない場合のみvalue属性にセット -->
    </div>
    <div class="element_wrap">
      <label>メールアドレス</label>
      <input type="mail" name="email" value="<?php if (!empty($clean['email'])) {
                                                  echo $clean['email'];
                                                } ?>">
    </div>
    <div class="element_wrap">
      <label>性別</label>
      <label for="gender_male"><input id="gender_male" type="radio" name="gender" value="male">男性</label>
      <label for="gender_female"><input id="gender_female" type="radio" name="gender" value="female">女性</label>
    </div>
    <div class="element_wrap">
      <label>年齢</label>
      <select name="age">
        <option value="">選択してください</option>
        <option value="1">〜19歳</option>
        <option value="2">20歳〜29歳</option>
        <option value="3">30歳〜39歳</option>
        <option value="4">40歳〜49歳</option>
        <option value="5">50歳〜59歳</option>
        <option value="6">60歳〜</option>
      </select>
    </div>
    <div class="element_wrap">
      <label>お問い合わせ内容</label>
      <textarea name="contact"></textarea>
    </div>
    <div class="element_wrap">
      <label for="agreement"><input id="agreement" type="checkbox" name="agreement" value="1">プライバシーポリシーに同意する</label>
    </div>
    <input type="submit" name="btn_confirm" value="入力内容を確認する">
  </form>

  <?php endif; ?>
</body>

</html>


##参考記事
フォームの基本構造を作成する | GRAYCODE PHPプログラミング

21
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?