ウェブデザイナー・コーダーを目指している皆さん、実際に仕事として取り組まれている皆さん、急に「とりあえず動くフォームが欲しい」とクライアントに言われた時、対応できますか?
頭では仕組みを理解していても、いざという時すぐに作れないのがフォームのややこしいところです。
そこであまり経験のない初心者の方向けに、コピペで動くPHPフォームテンプレートをご用意しました。記事後半では簡単な解説を用意していますので、そちらも是非ご活用ください。
フォームの仕様
今回のフォームの仕様を下記にまとめました。
- 入力画面 / 確認画面 / 完了画面の3構成
- バリデーション(※入力間違い防止のため)
- 通常の入力欄の他、ラジオボタン・チェックボックス・セレクトボックスに対応
- 迷惑メール防止機能はオミット
- 不正アクセス防止機能はオミット
迷惑メール防止機能としてGoogleが提供するreCAPTCHAの使用が効果的ですが、今回は急ぎで作るため省略します。
また入力画面を介さずに、いきなり確認画面にアクセスした場合は不正アクセスとしてサイトトップなどに転送するのが一般的ですが、これも省略します。
上記の通り迷惑行為に対する耐性が無いので、このフォームを設置したらずっと放置ではなく、あくまで緊急用で用が済んだら削除するのが好ましいと思います。
とりあえずコードです
下記のindex.php, confirm.php, complete.phpを同じディレクトリに入れるだけで動作します。
①入力画面(index.php)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>問い合わせフォーム</title>
<link rel="stylesheet" href="css/style.css">
<script src="js/common.js"></script>
</head>
<body>
<h1>問い合わせフォーム テンプレート</h1>
<h2>問い合わせ入力画面</h2>
<section id="form">
<form action="confirm.php" method="POST" name="form">
<input type='hidden' name='modeTo' value="confirm">
<div class="formRow">
<label for="firstname">姓<span class="require">必須</span></label>
<input type="text" name="firstname" id="firstname" placeholder="例)山田" value="" required>
</div>
<div class="formRow">
<label for="lastname">名<span class="require">必須</span></label>
<input type="text" name="lastname" id="lastname" placeholder="例)太郎" value="" required>
</div>
<div class="formRow">
<label for="firstname_kana">姓(カタカナ)<span class="any">任意</span></label>
<input type="text" name="firstname_kana" id="firstname_kana" placeholder="例)ヤマダ" value="">
</div>
<div class="formRow">
<label for="lastname_kana">名(カタカナ)<span class="any">任意</span></label>
<input type="text" name="lastname_kana" id="lastname_kana" placeholder="例)タロウ" value="">
</div>
<div class="formRow">
<label for="email">メールアドレス<span class="require">必須</span></label>
<input type="text" name="email" id="email" placeholder="例)example@mail.com" value="" required>
</div>
<div class="formRow">
<label for="tel">電話番号<span class="require">必須</span></label>
<input type="text" name="tel" id="tel" placeholder="例)06-1234-5678" required>
</div>
<div class="formRow">
<label for="sex">性別<span class="require">必須</span></label>
<input type="radio" name="sex" value="男性" checked>男性
<input type="radio" name="sex" value="女性">女性
</div>
<div class="formRow">
<label for="inquiry">お問い合わせ内容</label>
<select name="inquiry" id="inquiry" required>
<option value="">お問い合わせ内容を選択してください</option>
<option value="ご質問・お問い合わせ">ご質問・お問い合わせ</option>
<option value="ご意見・ご感想">ご意見・ご感想</option>
</select>
</div>
<div class="formRow">
<label for="contact_method">ご希望の連絡方法<span class="require">必須</span></label>
<input type="checkbox" name="contact_method" value="電話" checked>電話
<input type="checkbox" name="contact_method" value="メール">メール
<input type="checkbox" name="contact_method" value="どちらでもよい">どちらでもよい
</div>
<div class="formRow">
<label for="textarea">メッセージ本文<span class="require" required>必須</span></label>
<textarea name="textarea" rows="5" placeholder="お問い合わせ内容を入力してください。"></textarea>
</div>
<div class="formRow">
<button type="submit">確認画面へ</button>
</div>
</form>
</section>
</body>
</html>
②確認画面(confirm.php)
<?php
// 送信ボタンを押したら
if (isset($_POST['modeTo'])) {
if ($_POST['modeTo'] === 'confirm') {
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$firstname_kana = $_POST["firstname_kana"];
$lastname_kana = $_POST["firstname_kana"];
$tel = $_POST["tel"];
$email = $_POST["email"];
$sex = $_POST["sex"];
$inquiry = $_POST["inquiry"];
$contact_method = $_POST["contact_method"];
$textarea = $_POST["textarea"];
}
}
// 送信ボタンを押したら
if (isset($_POST['modeTo'])) {
if ($_POST['modeTo'] === 'send') {
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$firstname_kana = $_POST["firstname_kana"];
$lastname_kana = $_POST["firstname_kana"];
$tel = $_POST["tel"];
$email = $_POST["email"];
$sex = $_POST["sex"];
$inquiry = $_POST["inquiry"];
$contact_method = $_POST["contact_method"];
$textarea = $_POST["textarea"];
// 日本語エンコード
mb_language("ja");
mb_internal_encoding("UTF-8");
// 件名を$subjectに格納
$subject = "[自動送信]お問い合わせ内容の確認";
// メール本文を$bodyに格納
$body=<<<EOM
{$firstname}{$lastname} 様
お問い合わせありがとうございます。
以下のお問い合わせ内容を、メールにて確認させていただきました。
===================================================
【 お名前 】
{$firstname}{$lastname}
【 フリガナ 】
{$firstname_kana}{$lastname_kana}
【 メール 】
{$email}
【 電話番号 】
{$tel}
【 性別 】
{$sex}
【 お問い合わせ内容 】
{$inquiry}
【 ご希望の連絡方法 】
{$contact_method}
【 メッセージ本文 】
{$content}
===================================================
内容を確認のうえ、回答させて頂きます。
しばらくお待ちください。
EOM;
// 送信元のメールアドレスを$fromに格納
$from = "example@mail.address";
// 差出人の名前を$fromnameに格納
$fromname = "問い合わせフォーム";
// ヘッダ情報を$headerに格納する
$header = "From: " .mb_encode_mimeheader($fromName) ."<{$from}>";
// 第五引数を設定
$addParam = '-f'.$email;
// 送信する
mb_send_mail($email,$subject,$body,$header,$addParam);
// 送信完了後、完了画面に遷移させる
header("Location: https://example.com/complete.php");
exit;
}}
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>問い合わせ確認画面</title>
<link rel="stylesheet" href="css/style.css">
<script src="js/common.js"></script>
</head>
<body>
<h1>問い合わせフォーム テンプレート</h1>
<h2>問い合わせ確認画面</h2>
<section id="form">
<form action="confirm.php" method="POST" name="form">
<input type='hidden' name='modeTo' value="send">
<input type="hidden" name="firstname" value="<?php echo $firstname; ?>">
<input type="hidden" name="lastname" value="<?php echo $lastname; ?>">
<input type="hidden" name="firstname_kana" value="<?php echo $firstname_kana; ?>">
<input type="hidden" name="lastname_kana" value="<?php echo $lastname_kana; ?>">
<input type="hidden" name="email" value="<?php echo $email; ?>">
<input type="hidden" name="tel" value="<?php echo $tel; ?>">
<input type="hidden" name="sex" value="<?php echo $sex; ?>">
<input type="hidden" name="inquiry" value="<?php echo $inquiry; ?>">
<input type="hidden" name="contact_method" value="<?php echo $contact_method; ?>">
<input type="hidden" name="textarea" value="<?php echo $textarea; ?>">
<div class="formRow">
<label for="firstname">姓<span class="require">必須</span></label>
<p><?php echo $firstname; ?></p>
</div>
<div class="formRow">
<label for="lastname">名<span class="require">必須</span></label>
<p><?php echo $lastname; ?></p>
</div>
<div class="formRow">
<label for="firstname_kana">姓(カタカナ)<span class="require">必須</span></label>
<p><?php echo $firstname_kana; ?></p>
</div>
<div class="formRow">
<label for="lastname_kana">名(カタカナ)<span class="require">必須</span></label>
<p><?php echo $lastname_kana; ?></p>
</div>
<div class="formRow">
<label for="email">メールアドレス<span class="require">必須</span></label>
<p><?php echo $email; ?></p>
</div>
<div class="formRow">
<label for="tel">電話番号<span class="require">必須</span></label>
<p><?php echo $tel; ?></p>
</div>
<div class="formRow">
<label for="sex">性別<span class="require">必須</span></label>
<p><?php echo $sex; ?></p>
</div>
<div class="formRow">
<label for="inquiry">お問い合わせ内容</label>
<p><?php echo $inquiry; ?></p>
</div>
<div class="formRow">
<label for="contact_method">ご希望の連絡方法<span class="require">必須</span></label>
<p><?php echo $contact_method; ?></p>
</div>
<div class="formRow">
<label for="textarea">メッセージ本文<span class="require">必須</span></label>
<p><?php echo $textarea; ?></p>
</div>
<div class="formRow">
<button type="button" value="内容を修正する" onclick="history.back()">内容を修正する</button>
<button type="submit" name="submit">送信する</button>
</div>
</form>
</section>
</body>
</html>
③完了画面(complete.php)
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>問い合わせ完了画面</title>
<link rel="stylesheet" href="css/style.css">
<script src="js/common.js"></script>
</head>
<body>
<h1>問い合わせフォーム テンプレート</h1>
<h2>問い合わせ完了画面</h2>
<section id="complete">
<p>送信が完了しました。</p>
</section>
</body>
</html>
コード解説(初心者の方向け)
全体的に見て何のことはないフォームです。フォームタグのマークアップについて学習が完了していれば問題はないでしょう。
以下、各ファイルについて順に解説していきます。
①入力画面(index.php)
まずは入力画面。
<form action="confirm.php" method="POST" name="form">
フォーム上のデータのやり取りはPOSTで行います。送信先は同ディレクトリのconfirm.phpにしてください。
<input type='hidden' name='modeTo' value="confirm">
入力欄を設ける前に、type属性でhiddenを指定したinputをひとつ置いてやります。
次の項で詳しく解説しますが、このinputは入力画面→確認画面へ進んだことを判定するロジックとなります。
<div class="formRow">
<label for="firstname">姓<span class="require">必須</span></label>
<input type="text" name="firstname" id="firstname" placeholder="例)山田" value="" required>
</div>
各フォームの入力欄については自由にやってください。
labelタグのfor属性と、対応する入力欄のname属性を一致させることをお忘れなく。
またここでは簡易的なバリデーションとして、required属性を付与しています。
②確認画面(confirm.php)
続いては確認画面です。
<?php
// 送信ボタンを押したら
if (isset($_POST['modeTo'])) {
if ($_POST['modeTo'] === 'confirm') {
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$firstname_kana = $_POST["firstname_kana"];
$lastname_kana = $_POST["firstname_kana"];
$tel = $_POST["tel"];
$email = $_POST["email"];
$sex = $_POST["sex"];
$inquiry = $_POST["inquiry"];
$contact_method = $_POST["contact_method"];
$textarea = $_POST["textarea"];
}
}
?>
index.phpからPOSTで送信したデータは、このconfirm.phpで一度受け取らせます。
まず最初の行のif (isset($_POST[‘modeTo’])) で、先の項で触れた <input type=’hidden’ name=’modeTo’>があるか判定させています。
また if ($_POST[‘modeTo’] === ‘confirm’)は入力画面で送信したinput name=’modeTo’ にvalue属性としてconfirmが指定されているかを判定させています。
この2つの条件がそろった場合、入力画面→確認画面へ進んだということになります。
この時POSTで受け取った入力欄のデータを、個別に変数に格納しておきます。
$”inputのname属性の名前” = $POST[“inputのname属性の名前”] とすると分かりやすいと思います。
<form action="confirm.php" method="POST" name="form">
<input type='hidden' name='modeTo' value="send">
少し行を飛ばして、formタグの方へ。
確認画面ではユーザーが入力・選択した内容を確認させ、送信させます。
①で触れたのと同じく、データ送信にはPOSTを指定します。
actionにはこのconfirm.phpをもう一度指定してやります。
その下の<input type=’hidden’ name=’modeTo’ value=”send”> も①と同じ。
ただ今度は確認画面→送信完了のステップに切り替わったことを認識させたいので、valueをsendとしておきます。
<input type="hidden" name="firstname" value="<?php echo $firstname; ?>">
<input type="hidden" name="lastname" value="<?php echo $lastname; ?>">
<input type="hidden" name="firstname_kana" value="<?php echo $firstname_kana; ?>">
<input type="hidden" name="lastname_kana" value="<?php echo $lastname_kana; ?>">
<input type="hidden" name="email" value="<?php echo $email; ?>">
<input type="hidden" name="tel" value="<?php echo $tel; ?>">
<input type="hidden" name="sex" value="<?php echo $sex; ?>">
<input type="hidden" name="inquiry" value="<?php echo $inquiry; ?>">
<input type="hidden" name="contact_method" value="<?php echo $contact_method; ?>">
<input type="hidden" name="textarea" value="<?php echo $textarea; ?>">
また先ほどindex.phpからconfirm.phpに送った際、受け取った入力欄のデータを変数に格納したと思います。それをここで、type=”hidden”指定したinputに代入しておきます。
①から②に進んだ時点で、POSTで送信したデータは失われてしまいます。
その為、一旦メモ代わりのつもりで変数に格納、再度inputに代入するわけですね。
<div class="formRow">
<button type="button" value="内容を修正する" onclick="history.back()">内容を修正する</button>
<button type="submit" name="submit">送信する</button>
</div>
最後の行では送信ボタンの他に、内容を修正するボタンを設けています。内容に誤りがあった場合、ユーザーはこのボタンを押して前ページに戻ることが出来ます。
buttonタグに onclick=”history.back()” と記載することで、直前まで開いていたページ = index.phpにブラウザバックさせることが可能です。
POSTで送信したデータは失われていると書きましたが、前ページのブラウザキャッシュは残ったままなので、入力値・選択値は保持されているはずです。
②確認画面 2回目(confirm.php)
<?php
// 送信ボタンを押したら
if (isset($_POST['modeTo'])) {
if ($_POST['modeTo'] === 'send') {
$firstname = $_POST["firstname"];
$lastname = $_POST["lastname"];
$firstname_kana = $_POST["firstname_kana"];
$lastname_kana = $_POST["firstname_kana"];
$tel = $_POST["tel"];
$email = $_POST["email"];
$sex = $_POST["sex"];
$inquiry = $_POST["inquiry"];
$contact_method = $_POST["contact_method"];
$textarea = $_POST["textarea"];
// 日本語エンコード
mb_language("ja");
mb_internal_encoding("UTF-8");
// 件名を$subjectに格納
$subject = "[自動送信]お問い合わせ内容の確認";
// メール本文を$bodyに格納
$body=<<<EOM
{$firstname}{$lastname} 様
お問い合わせありがとうございます。
以下のお問い合わせ内容を、メールにて確認させていただきました。
===================================================
【 お名前 】
{$firstname}{$lastname}
【 フリガナ 】
{$firstname_kana}{$lastname_kana}
【 メール 】
{$email}
【 電話番号 】
{$tel}
【 性別 】
{$sex}
【 お問い合わせ内容 】
{$inquiry}
【 ご希望の連絡方法 】
{$contact_method}
【 メッセージ本文 】
{$content}
===================================================
内容を確認のうえ、回答させて頂きます。
しばらくお待ちください。
EOM;
// 送信元のメールアドレスを$fromに格納
$from = "example@mail.address";
// 差出人の名前を$fromnameに格納
$fromname = "問い合わせフォーム";
// ヘッダ情報を$headerに格納する
$header = "From: " .mb_encode_mimeheader($fromName) ."<{$from}>";
// 第五引数を設定
$addParam = '-f'.$email;
// 送信する
mb_send_mail($email,$subject,$body,$header,$addParam);
// 送信完了後、完了画面に遷移させる
header("Location: https://example.com/complete.php");
exit;
}}
?>
少し戻ります。
確認画面から送信ボタンを押すと、データは再度このconfirm.phpに送信されます。
そして<input type=’hidden’ name=’modeTo’> で value=”send” と指定していたので、今度はこちらのロジックが発動するわけですね。
最初にPOSTした値を変数に格納するのは同じですが、それ以降は暗記する呪文だという風に考えてもらっても大丈夫です。いきなり初心者の方にこれを理解させるのは難しいかもしれません。
一応、呪文が何をしているのか解説しておきます。
<?php
// 日本語エンコード
mb_language("ja");
mb_internal_encoding("UTF-8");
// 件名を$subjectに格納
$subject = "[自動送信]お問い合わせ内容の確認";
?>
ここではまず日本語エンコードを行っています。
この処理を行わないと、実際のメールの文章が文字化けしたりする事故が発生します。
その次はメールの件名を作成して、$subjectに代入しています。
件名のテキストは自由に変えてください。
<?php
// メール本文を$bodyに格納
$body=<<<EOM
{$firstname}{$lastname} 様
お問い合わせありがとうございます。
以下のお問い合わせ内容を、メールにて確認させていただきました。
===================================================
【 お名前 】
{$firstname}{$lastname}
【 フリガナ 】
{$firstname_kana}{$lastname_kana}
【 メール 】
{$email}
【 電話番号 】
{$tel}
【 性別 】
{$sex}
【 お問い合わせ内容 】
{$inquiry}
【 ご希望の連絡方法 】
{$contact_method}
【 メッセージ本文 】
{$content}
===================================================
内容を確認のうえ、回答させて頂きます。
しばらくお待ちください。
EOM;
?>
この部分ではメールの本文を作成して、$bodyに代入させています。
<?php
// 送信元のメールアドレスを$fromに格納
$from = "example@mail.address";
// 差出人の名前を$fromnameに格納
$fromname = "問い合わせフォーム";
// ヘッダ情報を$headerに格納する
$header = "From: " .mb_encode_mimeheader($fromName) ."<{$from}>";
// 第五引数を設定
$addParam = '-f'.$email;
// 送信する
mb_send_mail($email,$subject,$body,$header,$addParam);
// 送信完了後、完了画面に遷移させる
header("Location: https://example.com/complete.php");
exit;
}}
?>
ここではメールの送信元・送信先などのメタ情報の設定を行っています。
それぞれ、
$from には送信元(差出人)のメールアドレス
$fromname には送信元(差出人)の名前や企業名など
を記載しましょう。
ヘッダ情報は必須ではあるのですが、詳しい解説はここではやめておきます。
それよりも重要なのが $addParam です。
これを設定することで相手に自動返送メールが届く確率が大幅に高まります。
mb_send_mail(); は送信処理を示します。
最後に header(); に完了画面のURLを記載して exit; でシメれば完成です!
③完了画面(complete.php)
先ほどheader(); で指定したURLにはこのファイルを置いておきましょう。
Webデザイナーを目指すあなたへ
以下の記事では、Webデザインスクールの厳選3校をご紹介しています。
是非参考にしてみてくださいね。