トップへ戻る
BLOGS

WordPress 自作メールフォーム実装

WordPress 自作メールフォーム実装

今回は以前に初めて作成したPHPを使用した

コンタクトフォームを模倣、改良、バージョンアップさせて、自分で運営しているWordPressサイトで、プラグインなしで実際に使用できるように実装までしたいと思います。

ということで復習も兼ねて概念的な部分をしっかりとおさらいしていこうと思います

お問い合わせフォーム概念図

  • 入力画面の実装
  • 確認画面
  • 完了画面

これら3つのページから成るお問い合わせページを造ります

そしてこれらのページをユーザーが表示しようと何かしらのアクションをしてサーバーに問い合わせを行うリクエストは基本的には「GET」で呼び出されることになりますがHTMLのフォームタグでこれを制御してやることで

「確認画面」と実際にメールを送信する「完了画面」「POST」で呼び出すようにします。

これをコードで表現することでエラーを出したり、メールを送信したりという一連の流れが実現できます。

今回は上記の3つのファイルを一つのファイル

page-contact.phpのみで作成するようにします一枚のファイルに纏めるメリットとしては

  • 同じ記述を一つにまとめられる
  • ページが同じなので遷移するのもスムーズ
  • 処理をまとめることで視認性が上がりメンテナンス性の向上が見込める
  • 自身のプログラミング設計の練習になる

こんなところです

これから長く使用するためメンテナンス性も備えてバージョンアップにも即座に対応できるようにします。

それでは入力画面を制作します

今回はファイル一枚で作成するということで

フォームタグのアクション属性は自身のページに遷移するようにしておきます。

 <form action="./page-contact.php" method="POST" novalidate>

確認画面を表示するにはどうするか?

フォームを入力してサブミットボタンを押した際は

フォームタグに記述したようにPOSTでのリクエストが行くはずなので一旦、その条件で分岐させます

PHPにはスーパーグローバル変数というものがあらかじめ定義されていて、$_POST[‘fullname’]という連想配列にカッコの中のキーによって値が格納されている

ということはひとまず条件分岐としては

if ($_POST) {POSTリクエスト時の処理}

else{GETリクエストの処理}とすれば良さそうですね

しかしそれでは戻るボタンを押された時に成立しなくなってしまいます。

更にこの後完了画面を作成する際の条件を考察しなくてはいけません。

そこで、

入力画面:

GETまたは$_POST[‘back’]

確認画面:

$_POST[‘confirm’]

完了画面:

$_POST[‘send’]

というように各値をグローバル変数に入れて条件分岐できればうまくいきそうですね。

条件を変数にして管理する

ここでは上の条件を変数$modeに代入することで条件分岐の式にできるようにして管理ます。

$mode = 'input';
if ( isset($_POST['back']) && $_POST['back'] ) {
  //何もしない
} else if ( isset($_POST['confirm']) && $_POST['confirm'] ) {
  $mode = 'confirm';
} else if ( isset($_POST['send']) && $_POST['send'] ) {
  $mode = 'send';
}

isset($_POST[‘back’])でこの配列がそもそも存在しているかどうかを判定しています、そして&& $_POST[‘back’]で、

「かつ、その配列がセットされているか」を判定し両方がtrueの場合に変数にセットされた値をチェンジします。

これをページの最上部で定義してあげることで

HTMLのタグの中で条件分岐を記述できますね

 if ($mode == 'input') { ?>
  <!-- 入力画面 -->
<?php } else if ( $mode == 'confirm'){ ?>
<!-- 確認画面 -->
<?php } else {?>
    <!-- 送信時の処理 -->

このそれぞれのタグで囲ってやることでうまく条件を切り分けることが出来ました。

入力された値を保持する$_SESSION 変数

$_SESSION 変数を使用し入力してもらった値をサーバー上に保持します

どのようなタイミングで処理をするかというと、、

変数モードがconfirmに切り替わるタイミングですね、つまり

入力画面で入力を終えて送信したタイミングでセッション変数を定義して代入してあげます

セッション変数の概要としてこれで保存されるのは

ユーザーごと、ブラウザごととなっております。

session_start();

セッション変数を使うときのお約束ですね、最上部で定義してから使いましょう

else if ( isset($_POST['confirm']) && $_POST['confirm'] ) {
  $_SESSION['fullname'] = $_POST['fullname'];
  $_SESSION['email']    = $_POST['email'];
  $_SESSION['subject']  = $_POST['subject'];
  $_SESSION['message']  = $_POST['message'];
・・・(略)・・

これで渡ってきた値を代入することが出来ました

また、

} else {
  unset($_SESSION);
}

最後のelseで最初にこのページに来た際の分岐としてセッション変数を空にしておく動作を追記しておきます。

※ $_SESSION = array();$_SESSION[‘email’] = “”;の記述で問題ないはずですがなぜかうまく動作せず条件分岐しているにも関わらず強制的に実行されてしまっていたので上記の書き方にしました。

そしてHTMLですがセッション変数に値を代入するので

まず入力画面のinputタグvalueの値に

echo $_SESSION[‘fullname’]のように$_POSTから値を取るのではなくセッション変数を置いておくことで[‘back’]ボタンから戻ってきた場合に値がセットされているようにします。

また確認画面の入力された値を出すところも同様の記述で良いですね

これで確認画面のコードがこうなりました

これでだいぶ様になってきたので次は完了画面と送信処理ですね

メールを送信して完了画面を出す

ここで考察するのは完了画面の状況です

  • sendモードの条件分岐であること
  • メールを送信すること
  • セッション変数をクリアにすること
  • 完了画面を出すこと

そしてメール送信する関数が様々存在するので別のファイルに関数だけ用意してFTPでアップロードし、これにアクセスしてメールが飛ぶかどうか確認を怠らないようにしましょう。

//PHP関数
mail($宛先,$題名subject,$内容\r\n改行の確認コード);

//センドメール
mb_language("ja");
mb_internal_encoding("UTF-8");
mb_send_mail($宛先,$題名subject,$内容\r\n改行の確認コード);

//WordPress関数
wp_mail($宛先,$題名subject,$内容\r\n改行の確認コード);

確認ができたら受け取ったセッション変数から値をメールようにセットする変数($内容)を用意して送信処理を書きましょう

・・・(略)・・
} else if ( isset($_POST['send']) && $_POST['send'] ) {
  $message = "お問い合わせを受け付けました。\r\n"
            ."名前:".$SESSION['fullname']."\r\n"
            ."メールアドレス:".$SESSION['email']."\r\n"
            ."お問い合わせ内容:\r\n"
            .preg_replace("/\r\n|\r|\n/","\r\n",$SESSION['message']);
  wp_mail($SESSION['email'],'お問い合わせありがとうございます',$message);
  wp_mail('hogehoge@gmail.com','お問い合わせを頂きました',$message);
  $mode = 'send';
・・・(略)・・

\r\nはメールでの改行コードです

$messageの内容を全て「.」ドットで繋いで連結させています

preg_replace()の関数は$SESSION[‘message’]の値の中から

「\r\n」「\r」「\n」の改行の記述を

全て「\r\n」に変換するという関数です

wp_mailは二通送信者の自動送信メールと宛先名は私のアドレスへ、ということですね。

これでメールフォーム自体は機能しちゃんとメールを送信することができるようになりました。次はこの機能を保護する意味でも入力チェックを施します

各入力項目チェックの設計をする

  • 名前欄:  入力必須、100文字以内
  • メール欄: 入力必須、200文字以内、Eメール形式
  • 題名:   100文字以内
  • 本文:   入力必須、500文字以内

として考えます

こうして入力された値をチェックすることをバリデーションと言います。

これらの条件分岐を入力画面にて設定しておきエラーを出すようにします

また文字入力される際にプログラミング言語などを入力され、不正に操作されるクロスサイトスクリプティング(XSS攻撃)に対応できるように入れられたプログラミング言語を無害化するためのサニタイズを行います

一つづつ解説します

$err_msg = array();を最初に定義しておきます

if (!$_POST[‘fullname’])で名前の項目が入っているかの確認をしています、そして値がなければ

$err_msg[] = “名前を入力してください。”;のようにして

先に定義した空の配列に文字列をどんどん追加して行きます

else if ( mb_strlen($_POST[‘fullname’]) > 100 )

mb_strlen関数で文字列の字数を数えることができるのでこれで100文字以内という条件になります。

htmlspecialcharsはコードの無害化サニタイズをしてくれる関数になっていて引数として、値、シングルクォーテーションを含むかどうか、エンコードするcharsetを指定して使用します。

($_POST[‘fullname’], ENT_QUOTES, “UTF-8”);

あとはメールアドレスに関しては前回から引き続き

!filter_var関数で書式を判定しています。

それらを全て適用できたら、

HTML側で設定している$modeが変わらないようにエラー判定して条件分岐させます

if ($err_msg) {
    $mode = 'input';
  } else {
    $mode = 'confirm';
  }

エラーメッセージを表示するHTML

上記のエラー判定で$modeがinputのままなので入力画面にエラーメッセージが出るように条件を記述します

<!-- 入力画面 -->
  <div class="contact">
  <?php
  if ($err_msg) {
    echo '<div class="err_msg">';
    echo implode('<br>',$err_msg );
    echo '</div>';
  }

フォーム完成のまとめ

これで一通りのコードを書いてお問い合わせフォームを実装することが出来ました

最後に完成したコードを載せておきます

コメントをお待ちしております

お気軽にコメントをどうぞ。

CAPTCHA