PHPを使って、なるべく簡単にメールフォームを作る

PHPを使って、必要最低限の機能を持ったメールフォームを作ります。
今回は、3つのファイルを使って、メールフォームを作ります。少しコードが長くなるので、先に完成系を表示し、その後解説をしていく方法をとります。

1.処理の流れ

今回作るメールフォームの、処理の流れは以下の通りです。


1.お問い合わせを入力
  ┃
2.入力内容を確認
  ┃
3-1.NG(入力に戻る)
3-2.OK(送信へ)
  ┃
4.自動送信メールの送信
5.「ありがとうございましたの表示

2.各ファイル構成

各々のファイル名は、以下の通りです。
お問い合わせを入力するページ
index.html

入力されたものを確認するページ
check.php

実際にメールを送信するページ
send.php

コードは、以下の通りです。尚、doctypeの宣言や、html、headタグの記述などは省略します。
また、装飾目的のタグなども排除し、なるべくシンプルなhtmlで書いていきます。
実際に作るときは、もう少しhtmlの構造が複雑になると思います。

index.html
<form action="check.php" method="POST">
    お名前<br>
    <input type="text" name="onamae" id="onamae"><br>

    メールアドレス<br>
    <input type="text" name="email" id="email"><br>

    ご質問<br>
    <textarea id="question" name="question"></textarea><br>
    <input type="submit" value="この内容で次へ">
</form>

check.php
<?php

$onamae = htmlspecialchars($_POST['onamae']);
$email = htmlspecialchars($_POST['email']);
$question = htmlspecialchars($_POST['question']);

//入力チェックとエラーメッセージの登録
$flg = 0;
$onamae_note = '';
$email_note = '';
$question_note = '';

if (empty($onamae)) {
    $onamae_note = '<span class="attention">お名前を入力してください</span>';
    $flg = 1;
}
if (empty($email)) {
    $email_note = '<span class="attention">メールアドレスを入力してください</span>';
    $flg = 1;
} elseif (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $email)) {
    $email_note = '<span class="attention">メールアドレスの形式が正しくありません</span>';
    $flg = 1;
}

if (empty($question)) {
    $question_note = '<span class="attention">ご質問を入力してください</span>';
    $flg = 1;
}
?>
〜以下HTML〜

お名前<br>
<?php echo $onamae; ?>
<?php echo $onamae_note; ?>
<br>

メールアドレス<br>
<?php echo $email; ?>
<?php echo $email_note; ?>
<br>

ご質問<br>
<?php echo $question; ?>
<?php echo $question_note; ?>
<br>

<?php if ($flg == 1) : ?>
    <button onclick="history.back();">入力画面に戻る</button>
<?php else : ?>
    <form action="send.php" method="POST">
            <input type="hidden" name="onamae" value="<?php echo $onamae; ?>">
            <input type="hidden" name="email" value="<?php echo $email; ?>">
            <input type="hidden" name="question" value="<?php echo $question; ?>">
            <button type="button" onclick="history.back();">入力画面に戻る</button>
            <input type="submit" value="送信する">
    </form>
<?php endif; ?>

send.php
<?php
$onamae = htmlspecialchars($_POST['onamae']);
$email = htmlspecialchars($_POST['email']);
$question = htmlspecialchars($_POST['question']);

//自動返信メール
$email_title = 'お問い合わせありがとうございます';
$email_body = <<<mail
{$onamae}様

※こちらのメールは、自動返信メールです。
後ほど担当者よりご連絡いたします。
mail;

$email_from = 'From:xxx@xxx.xxx';

mb_internal_encoding("UTF-8");
mb_language("Japanese");
mb_send_mail($email,$email_title,$email_body,$email_from);

//担当者へメール
$tanto_address = "tanto@xxx.xxx";
$tanto_title = "お申し込みがありました";
$tanto_body =<<<tanto
ホームページよりお申し込みがありました。

お名前
{$onamae}様

メールアドレス
{$email}

ご質問
{$question}

tanto;

$tanto_from = "From:xxx@xxx.xxx";
mb_internal_encoding("UTF-8");
mb_language("Japanese");
mb_send_mail($tanto_address,$tanto_title,$tanto_body,$tanto_from);
?>
〜以下HTML〜
お問い合わせありがとうございました


3.解説

1.お問い合わせを入力(ここの解説)
  ┃
2.入力内容を確認
  ┃
3-1.NG(入力に戻る)
3-2.OK(送信へ)
  ┃
4.自動送信メールの送信
5.「ありがとうございましたの表示

まず、「1.お問い合わせを入力」について
formタグのaction属性で、データの送り先(今回の場合、check.php)を、methodでpostを指定します。

また、inputタグは、name属性に各々のデータのキー(名札)を入れます。
今回は、「onamae」、「email」、「question」の三つをname属性の値にしています。
ユーザーが実際にテキストボックスやテキストエリアに入力した値は、このname属性の値が、名札(キー)として付加され、check.phpへ送られます。

1.お問い合わせを入力
  ┃
2.入力内容を確認(ここの解説)
  ┃
3-1.NG(入力に戻る)
3-2.OK(送信へ)
  ┃
4.自動送信メールの送信
5.「ありがとうございましたの表示

次に、「2.入力内容を確認」の解説です。
ファイルは、check.phpです。

まず、index.htmlから送られた、「onamae」、「email」、「question」のデータを受け取らなければなりません。
それは、以下の部分です。
〜check.php〜
$onamae = htmlspecialchars($_POST['onamae']);
$email = htmlspecialchars($_POST['email']);
$question = htmlspecialchars($_POST['question']);

$onamae、$email、$questionは、変数です。
取得したデータを、格納します。
$_POST['キー名']
この書き方で、POSTで渡されたデータを取得します。
例えば、index.htmlから送られた、onamaeの値を取得したかった場合、
$_POST['onamae'];
となります。

htmlspecialcharsは、「<」や「>」など、htmlやプログラムで扱う時に特別な意味を持つ記号を、エスケープ処理するのに使います。
$_POST['キー名']で、入力された値をそのまま使ってしまうと、悪意のある人が、サーバー内を壊す様なプログラムを、index.htmlの入力欄から入力した場合、そのプログラムがそのままcheck.phpで動いてしまいます。
それを防ぐためにhtmlspecialcharsで、$_POST['キー名']で取得したデータを括っています。

そして、次の工程で、入力されたデータが存在するかどうか、又、emailの場合は、メールアドレスとして正しい値かを調べます。

〜check.php〜
//入力チェックとエラーメッセージの登録
$flg = 0;
$onamae_note = '';
$email_note = '';
$question_note = '';

まず、変数の準備をしています。
#flgは、まず0を代入してあります。
そして、「お名前」、「メールアドレス」、「ご質問」のどれか一つでも問題がある灰に、1を代入します。

$flgが0の時は、問題がない時。1の時は、問題がある時。

この様に、処理を分ける為に使います。

$xxx_noteは、「お名前」、「メールアドレス」、「ご質問」に問題があった場合、エラーメッセージを入力する為に使います。

次は、各々の項目のチェックです。

「お名前」が入力されて入るかチェックしています。
もし入力されていなかったら、$onamae_note にエラーメッセージを入力し、$flgに1を代入します。
〜check.php〜
if (empty($onamae)) {
    $onamae_note = '<span class="attention">お名前を入力してください</span>';
    $flg = 1;
}

順番を前後して、先に「ご質問」について解説します。
こちらも、「お名前」同様、入力されて入るかをチェックし、されていない場合は、$question_noteにエラーメッセージを入力し、$flgに1を代入します。
〜check.php〜
if (empty($question)) {
    $question_note = '<span class="attention">ご質問を入力してください</span>';
    $flg = 1;
}

最後に「メールアドレス」です。
メールアドレスのチェックは、二つのチェックで成り立っています。
a.入力されているか
b.入力された値が、メールアドレスとして、正しいか

まず、aについては、今までの「お名前」、「ご質問」と同様です。
empty($email)の時(要は$emailに値が入力されていない時)に、
$email_noteにエラーメッセージを、$flgに1を代入します。
〜check.php〜
if (empty($email)) {
    $email_note = '<span class="attention">メールアドレスを入力してください</span>';
    $flg = 1;
}elseif(xxx以下略xxx

次は、bについてです。

〜check.php〜
先の記述は略
 elseif (!preg_match("/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/", $email)) {
    $email_note = '<span class="attention">メールアドレスの形式が正しくありません</span>';
    $flg = 1;
}

preg_match(正規表現パターン,値)は、引数として値の中に、正規表現パターンがあるかどうかを調べます。
本コードの場合、
正規表現パターンは、「"/^([a-zA-Z0-9])+([a-zA-Z0-9\._-])*@([a-zA-Z0-9_-])+([a-zA-Z0-9\._-]+)+$/"」に当たります。これは、メールアドレスのフォーマットを表します。
値は、$emailになります。

つまり、$email(入力されたメールアドレス)が、メールアドレスのフォーマットとして正しいかどうかを調べています。

最後に、今やりたいのは、「正しくない時」に$email_noteと$flgに値を入れたいので、「!」を付けています。

次にHTMLで入力された内容を表示しています。

〜check.php〜
お名前<br>
<?php echo $onamae; ?>
<?php echo $onamae_note; ?>
<br>

メールアドレス<br>
<?php echo $email; ?>
<?php echo $email_note; ?>
<br>


ご質問<br>
<?php echo $question; ?>
<?php echo $question_note; ?>
<br>

もし、$onamaeが入力されていた場合は、$onamae_noteは、空っぽになります。一つ上の工程の、エラーチェックで、エラーではない、つまり$onamae_noteには、値が代入されていないはずだからです。
$emailも$questionも同様です。

1.お問い合わせを入力
  ┃
2.入力内容を確認
  ┃
3-1.NG(入力に戻る)(ここの解説)
3-2.OK(送信へ)(ここの解説)
  ┃
4.自動送信メールの送信
5.「ありがとうございましたの表示

入力内容が確認できたので、次はその入力内容に応じて、処理を分けます。
if文で、エラーがあった時となかった時で条件分岐します。
そこで使うのが、$flgです。
「お名前」、「メールアドレス」、「ご質問」のどれか一つでも入力内容に問題がある場合、$flgには1が代入されています。
よって、if文で$flgが1の時とそうじゃ無い時で、条件分岐させます。

〜check.php〜
<?php if ($flg == 1) : ?>
    <!--エラーの時-->
    <button onclick="history.back();">入力画面に戻る</button>
<?php else : ?>
    <!--エラーじゃない時-->
    <form action="send.php" method="POST">
            <input type="hidden" name="onamae" value="<?php echo $onamae; ?>">
            <input type="hidden" name="email" value="<?php echo $email; ?>">
            <input type="hidden" name="question" value="<?php echo $question; ?>">
            <button type="button" onclick="history.back();">入力画面に戻る</button>
            <input type="submit" value="送信する">
    </form>
<?php endif; ?>

エラーの時の処理は単純で、一つ前のページに戻しています。
javascriptのhistory.backで戻しています。

エラーじゃなかった時は、次のページ(send.php)へ遷移させるための「送信する」ボタンを表示します。
この時、type="hidden"のinputタグで、値を送っています。
nama属性とvalue属性が、各々以下の組み合わせです。
onamae  :$onamae
email      :$email
question:$question

このhiddenでのデータ送信が無いと、次のページ(send.php)へデータを送る事ができず、当然send.phpでもデータを受け取る事ができません。

1.お問い合わせを入力
  ┃
2.入力内容を確認
  ┃
3-1.NG(入力に戻る)
3-2.OK(送信へ)
  ┃
4.自動送信メールの送信(ここの解説)
5.「ありがとうございましたの表示

まず、send.phpでも、check.phpからPOSTで送られた値を受け取ります。
〜send.php〜
$onamae = htmlspecialchars($_POST['onamae']);
$email = htmlspecialchars($_POST['email']);
$question = htmlspecialchars($_POST['question']);

ここで受け取った値を元に、メールを送信します。
mb_send_mailが、「メールを送る」という関数です。mb_send_mailは4つの引数が必要です。
第一引数が「送信先」
第二引数が「メールのタイトル」
第三引数が「メールの本文」
第四引数が「メールの送信元」

以上を、各々用意します。
第一引数の送信先は、単純に$emailでOKです。$emailは、要するにユーザに入力されたメールアドレスです。
第二引数うのメールのタイトルは、$email_titleとしました。今回は、「お問い合わせありがとうございます」という文字列を代入しています。
〜send.php〜
$email_title = 'お問い合わせありがとうございます';

第三引数のメール本文は、$email_bodyとしました。
〜send.php〜
$email_body = <<<mail
{$onamae}様

※こちらのメールは、自動返信メールです。
後ほど担当者よりご連絡いたします。
mail;
ここの部分が、本文を代入して入る記述です。PHPのヒアドキュメントを使って記述してあります。
第四引数のメールの送信元は、$email_fromとしました。
〜send.php〜
$email_from = 'From:xxx@xxx.xxx';
ここの箇所で、送信元のメールアドレスを記述します。
今回は、「xxx@xxx.xxx」というメールアドレスからメールが送信されるようにしました。実際は、noreply@test.comなどのメールアドレスになります。

〜send.php〜
mb_internal_encoding("UTF-8");
mb_language("Japanese");
この2行で、メールの言語を日本語に、文字コードをUTF-8に設定しています。

これで、メールを送信するのに必要なデータが全て揃ったので、
〜send.php〜
mb_send_mail($email,$email_title,$email_body,$email_from);
この行で、送信しています。

担当者へのメールも、同様の手順で作成します。

1.お問い合わせを入力
  ┃
2.入力内容を確認
  ┃
3-1.NG(入力に戻る)
3-2.OK(送信へ)
  ┃
4.自動送信メールの送信
5.「ありがとうございましたの表示(ここの解説)

最後に、HTMLでありがとうございましたと表示します。

これでメールフォームの完成です。

4.まとめ

今回は、必要最低限のコードで、メールフォームを実装しました。
実際は、今回解説したコードに、CSSでの見栄えの調整が入ります。よって、HTMLコードももう少し複雑になりがちです。
ですが、メールフォームとしての働きそのものは、今回の物をベースにして良いと思います。
実際にサーバーにアップロードして動作を確認してみてください。