WordPress でプラグインを利用せずメールフォームを自作!画面遷移せず非同期処理で実装

WordPress で構築したサイトに「お問い合わせ」のメールフォームを設置する最も簡単な方法はプラグインの導入です。代表的なものとして、次の2つがよく利用されています。

これらのプラグインは汎用的に使えるよう設計されているため、テキストボックスだけでなくラジオボタンやプルダウンのような入力項目を設置することが可能です。ただ、ブログ用に簡易的に設置するには余計な機能が多すぎます。

しかもプラグインを導入することで、余計な JavaScript やスタイルシートのファイル読み込みが発生します。ページの読み込みを軽くするには、出来る限りプラグインを排除して、自作できるものは独自で組み込むのが理想的です。

そこで、プラグインを介さず簡易的なメールフォームを自作で設置する方法について、サンプルプログラムを用いて紹介していきます。

作成するオリジナルのメールフォーム【仕様】

  • 入力項目は名前・メールアドレス・ウェブサイト(URL)・内容のみ
  • URL 以外は入力必須チェックを実施
  • 簡易入力チェックは html 上で実施
  • 外部からのアクセスを排除するため、リファラチェックを行う
  • セキュリティの面から HTML 形式ではなくテキスト形式で送信
  • 日時や IP アドレス等の送信者情報も送信
  • 画面遷移せず非同期でメール送信処理を実施

ごくありふれたメールフォームですが、このメールフォームの最大の特徴は 画面遷移をしない 点です。つまり画面上から「送信」ボタンを押すと、画面遷移せずに処理結果を表示します。この非同期の仕組みにより、複数の画面を用意することなくシンプルな構成で実装することができるのです。

実装に必要な画面・ファイル

  • メールフォームを設置する固定ページ
  • メール送信用 PHP ファイル

用意するのはこれだけです。では、ソースコードをご覧ください。

メールフォーム実装【ソースコード】

固定ページ(HTML・CSS・JavaScript)

固定ページの入力画面に直接貼り付けられるように記しています。p タグや br タグが自動挿入されないように考慮しているため、見づらい部分もありますがご了承ください。

メールフォームソースコード【HTML・CSS・JavaScript】
<!-- HTML -->
<form id="mailform">
  <div>
    <label for="nameval">名前<span>(必須)</span></label> <input
    type="text" name="nameval" id="nameval" required />
  </div>
  <div>
    <label for="mailval">メールアドレス<span>(必須)</span></label> <input
    type="email" name="mailval" id="mailval" required />
  </div>
  <div>
    <label for="urlval">ウェブサイト</label> <input
    type="text" name="urlval" id="urlval" />
  </div>
  <div>
    <label for="textval">内容<span>(必須)</span></label> <textarea
    name="textval" id="textval" rows="12" required></textarea>
  </div>
  <p class="contact-submit">
    <input type="submit" value="送信 »" id="submit"> <input
    id="referrer" type="hidden" name="referrer" />
  </p>
</form>
<div id="dispmsg"></div>

<!-- スタイルシート -->
<div>
<style>
#mailform input[type='text'],
#mailform input[type='email'] {
  font-size: 16px;
  width: 300px;
  max-width: 100%;
  margin-bottom: 13px;
  box-sizing: border-box;
}
#mailform input,
#mailform button {
  height: 40px;
  padding: 0 10px;
}
#mailform textarea {
  margin-bottom: 13px;
  padding: 2px 5px;
  width:100%;
  box-sizing: border-box;
}
#mailform label {
  margin-bottom: 3px;
  font-weight: bold;
  display: block;
}
#mailform label span {
  color: #aaa;
  margin-left: 4px;
  font-weight: normal;
}
#submit{
  width:200px;
}
#dispmsg > p{
  border: 3px solid #ffe3b3;
  background: #ffffeb;
  border-radius: 7px;
  padding: 15px;
  margin: 30px 0;
  text-align: center;
  font-weight: bold;
}
#dispmsg blockquote {
  margin: 30px 0;
  padding: 15px;
  background-color: #f3f3f3
}
#dispmsg pre {
  font-family: -apple-system,BlinkMacSystemFont,Meiryo,Verdana,
  "Helvetica Neue","Segoe UI","Noto Sans Japanese","ヒラギノ角ゴ ProN W3",sans-serif;
  line-height: 1.7;
  white-space: pre-wrap;
  background: #fafafa;
  margin: 15px 0 0;
  padding: 10px;
}
#dispmsg #errmsg{
  background: #fff5f5;
  border: 3px solid #fcc;
  color: #e1536a;
}
</style>
</div>

<!-- JavaScript -->
<div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
jQuery(function ($) {
  $("#referrer").val(document.referrer);
  $("#mailform").submit(function(){ 
    $.ajax({
      url : 'PHPソースコードのパス',
      type: 'POST',
      dataType: 'json',
      data: $(this).serialize()
    })
    .done( function(data){
      $("#dispmsg").empty();
      $("#dispmsg").html(data.dispmsg);
      if(data.errflg != 1){
        $("#mailform").remove();
      }
    })
    .fail( function(data){
      alert('メール送信に失敗しました');
    })
    return false;
  });
});
</script>
</div>

スタイルシートと JavaScript は、テーマ内のファイルに記載しても構いません。ただ jQuery の Ajax 処理を利用しているため、jQuery のライブラリを利用していない場合は読み込む必要があります。ここでは 73 行目の処理で、Google の CDN からスクリプトのファイルを読み込んでいます。

jQuery ファイル読込みを CDN のライブラリから参照する方法
jQuery とは JavaScript のライブラリの一種で、スクリプトファイルを自身のサーバーにアップロードして参照する必要があります。呼び出し方は、他の...

なお JavaScript 部分の処理は、jQuery ライブラリの読み込み後に記載する必要があります。既に WordPress の設定で jQuery を読み込んでいても、</body> タグの直前に移動しているような場合はエラーになってしまうので、上記のように記載してください。(jQuery ファイルが二重で読み込まれても問題ありません。)

これらのスクリプト処理やスタイルシートは同画面でしか利用しないため、テーマ内のファイルに移すよりは、画面内で定義してしまうことをおすすめします。

CSS は現状設定しているものと重複する場合があるので、必要に応じて適宜変更してください。

79 行目の「PHPソースコードのパス」は、実際に作成する PHP のファイルパスに書き換えが必要になります。

メール送信用 PHP ファイル

メール送信部分は PHP で実装します。

メールフォームソースコード【sendmail.php】
<?php
// json 形式のデータを扱うための定義
header('Content-type: application/json');
// PHP5.1.0以上はタイムゾーンの定義が必須
date_default_timezone_set('Asia/Tokyo');

// --------------------------
// 個別設定項目(3つ)
// --------------------------
// 送信先メールアドレス
$to = 'xxxx@xxxx.com';
// メールタイトル
$subject = 'お問い合わせフォームより';
// ドメイン(リファラチェックと送信元メールアドレスに利用)
$domain = 'xxxx.xxxxxxxx.com';

//変数初期化
$errflg =0;    // エラー判定フラグ
$dispmsg ='';  // 画面出力内容

// 入力項目
$nameval = '';   // 名前
$mailval = '';   // メールアドレス
$urlval = '';    // ウェブサイト
$textval = '';   // 内容
$referrer = '';  // 遷移元画面

// 画面からのデータを取得
if(isset($_POST['nameval'])){ $nameval = $_POST['nameval']; }
if(isset($_POST['mailval'])){ $mailval = $_POST['mailval']; }
if(isset($_POST['urllval'])){ $urllval = $_POST['urllval']; }
if(isset($_POST['textval'])){ $textval = $_POST['textval']; }
if(isset($_POST['referrer'])){ $referrer = $_POST['referrer']; }

if(strpos($_SERVER['HTTP_REFERER'], $domain) === false){
  // リファラチェック
  $dispmsg = '<p id="errmsg">【リファラチェックエラー】お問い合わせフォームから入力されなかったため、メール送信できませんでした。</p>';
  $errflg = 1;
}
else if($nameval == '' || $mailval == '' || $textval == ''){
  //必須チェック
  $dispmsg = '<p id="errmsg">【エラー】名前・メールアドレス・内容は必須項目です。</p>';
  $errflg = 1;
}
else if(!preg_match("/^[\.!#%&\-_0-9a-zA-Z\?\/\+]+\@[!#%&\-_0-9a-z]+(\.[!#%&\-_0-9a-z]+)+$/", $mailval) || count( explode('@',$mailval) ) !=2){
  //メールアドレスチェック
  $dispmsg .= '<p id="errmsg">【エラー】メールアドレスの形式が正しくありません。</p>';
  $errflg = 1;
}
else{
  // メールデータ作成
  $subject = "=?iso-2022-jp?B?".base64_encode(mb_convert_encoding($subject,'JIS','UTF-8'))."?=";
  $message= '名前:'.$nameval."\n";
  $message.='メール:'.$mailval."\n";
  $message.='ウェブサイト:'.$urlval."\n";
  $message.="\n――――――――――――――――――――――――――――――\n\n";
  $message.=$textval;
  $message.="\n\n――――――――――――――――――――――――――――――\n";
  $message.='送信日時:'.date( "Y/m/d (D) H:i:s", time() )."\n";
  $message.='送信元IPアドレス:'.@$_SERVER["REMOTE_ADDR"]."\n";
  $message.='送信元ホスト名:'.getHostByAddr(getenv('REMOTE_ADDR'))."\n";
  $message.='リファラURL:'.$referrer."\n";
  $message.='お問い合わせページ:'.@$_SERVER['HTTP_REFERER']."\n";
  $message= mb_convert_encoding($message,'JIS','UTF-8');
  $fromName = mb_encode_mimeheader(mb_convert_encoding($nameval,'JIS','UTF-8'));
  $header ='From: '.$fromName.'<wordpress@'.$domain.'>'."\n";
  $header.='Reply-To: '.$mailval."\n";
  $header.='Content-Type:text/plain;charset=iso-2022-jp\nX-Mailer: PHP/'.phpversion();
  // メール送信
  $retmail = mail($to,$subject,$message,$header);

  // 送信結果の判定
  if( $retmail ){
    $dispmsg ='<p class="success">メールを送信しました。返信までしばらくお待ちください。</p>';
    $dispmsg.='<blockquote><p>名前: '.hsc_utf8($nameval).'<br />';
    $dispmsg.= 'メール: '.hsc_utf8($mailval).'<br />';
    $dispmsg.= 'ウェブサイト: '.hsc_utf8($urlval).'</p>';
    $dispmsg.= '<pre>'.hsc_utf8($textval).'</pre></blockquote>';
  }else{
    $dispmsg .= '<p id="errmsg">【エラー】メール送信に失敗しました。。</p>';
    $errflg = 1;
  }
}

// 処理結果を画面に戻す
$result = array('errflg'=>$errflg, 'dispmsg'=>$dispmsg);
echo json_encode( $result );

// HTMLエスケープ処理
function hsc_utf8($str) {
  return htmlspecialchars($str, ENT_QUOTES,'UTF-8');
}
?>

上記 PHP プログラムのダウンロードファイルを用意したのでご利用ください。

保存したファイルは zip 形式になっています。解凍した上で、プログラム内の個別設定項目(11, 13, 15 行目)を自身の環境に合わせて書き換えてください。

あとは FTP を使って任意の場所にアップロードし、このアップロードした場所に応じて、HTML 側の 79 行目「PHPソースコードのパス」を指定します。

メール送信プログラムの実装内容

実装画面のイメージ

上記のソースコードをそのまま利用すると、画面イメージは次のようになります。

入力フォーム画面イメージ

メールフォーム画面イメージ

メール送信 正常終了時の画面

メールフォームは画面から消えて、送信した情報が画面に表示されます。

メールフォーム 正常終了時の画面イメージ

メール送信 エラー時の画面

エラー時はメールフォームの情報はそのままで、送信ボタンの下部にエラーメッセージを表示します。

メールフォーム エラー時の画面イメージ

HTML5 のフォームオブジェクトで簡易入力チェック

メールアドレスのフォーマットチェックと、必須項目のチェックが html 上で行われます。正確にはブラウザ側がチェックをしてくれるもので、HTML5 により実装された機能です。

例えばメールアドレスの場合、input の type 属性は text でなく email を採用しています。これにより、不正なメールアドレスが入力された場合、送信時に入力エラーとしてメッセージが表示されます。ブラウザによって表示形式は異なりますが、概ね同様のチェックが行われます。

以下の画像は、Chrome ブラウザにてチェック処理が行われた場合の表示イメージになります。

メールフォーム メールアドレス入力チェック

必須項目は input タグに required の属性を追加することで、送信時に入力チェックが行われます。こちらも HTML5 の新機能になります。

メールフォーム 必須項目チェック

ブラウザが古い場合、これらのチェック機能が正しく動かないケースがあります。そのためサーバー側の PHP の処理においても、同様の入力項目チェックを用意しています。

変更が必要な箇所は4箇所

上記のソースコードを丸ごとコピーしても正しく動作しません。利用する環境に応じて、必ず次の項目を書き換えてください。

HTML 上の JavaScript
  • 79行目「PHPソースコードのパス」

例えばドメイン直下に PHP ファイルをアップロードした場合は、次のように記します。

  • url : ‘https://nj-clucker.com/sendmail.php’,
  • url : ‘/sendmail.php’,
PHP ファイル
  • 11行目「$to = ‘xxxx@xxxx.com’;」送信先のメールアドレス
  • 13行目「$subject = ‘お問い合わせフォームより’;」メールのタイトル
  • 15行目「$domain = ‘xxxx.xxxxxxxx.com’;」ドメイン

タイトルは固定にしているため PHP 上で定義しています。ドメインの定義は WordPress を設置しているトップレベルドメイン、もしくはサブドメインを定義してください。(WordPress の URL の http:// を除いた、次のスラッシュまでの文字列を設定します。)

PHP 上でリファラチェックを実施

PHP ファイルの 35 ~ 39 行目に該当する箇所です。

if(strpos($_SERVER['HTTP_REFERER'], $domain) === false){
  // リファラチェック
  $dispmsg = '<p id="errmsg">【リファラチェックエラー】お問い合わせフォームから入力されなかったため、メール送信できませんでした。</p>';
  $errflg = 1;
}

メールフォームを設置したページ以外からメールが送られないように制御しています。外部から不正にメール送信プログラムが呼び出されないようにするための処理です。この時チェックに利用しているのが、前項のドメイン変数です。

本来であれば .htaccess の設定で、外部ドメインからメール送信用 PHP ファイルにアクセスできないように制御するのが望ましいです。

PHP 上のアドレスチェックは簡易的なもの

PHP ファイルの 45 ~ 49 行目に該当する箇所です。

else if(!preg_match("/^[\.!#%&\-_0-9a-zA-Z\?\/\+]+\@[!#%&\-_0-9a-z]+(\.[!#%&\-_0-9a-z]+)+$/", $mailval) || count( explode('@',$mailval) ) !=2){
  //メールアドレスチェック
  $dispmsg .= '<p id="errmsg">【エラー】メールアドレスの形式が正しくありません。</p>';
  $errflg = 1;
}

正規表現を用いて入力チェックをしています。ただし、ここで実装しているものは不完全なチェックです。完璧なチェックをすると、とんでもなく巨大なソースコードになってしまうため、最低限のチェックに留めていることをご了承ください。

送信者は入力された名前を表示

PHP ファイルの 65 ~ 67 行目に該当する箇所です。

  $fromName = mb_encode_mimeheader(mb_convert_encoding($nameval,'JIS','UTF-8'));
  $header ='From: '.$fromName.'<wordpress@'.$domain.'>'."\n";
  $header.='Reply-To: '.$mailval."\n";

受信したメールの送信者の欄には、入力された「名前」の項目を表示します。ただし、送信元のメールアドレスは「wordpress@ドメイン名」となるように設定しています。

勿論、入力されたメールアドレスを利用する方法もあります。しかしメーラー(例えば Gmail)によっては、入力されたアドレスを利用すると自動的に迷惑メールに分類されてしまうケースがあるため、ここでは自身のドメインから送られたように実装しています。

一方で 67 行目の処理にて、返信先には入力されたメールアドレスを設定しているので、メーラーから「返信」する場合は、自動的に画面で入力されたメールアドレスが送信先に設定されます。

メールに出力される情報

このプログラムに従ってメールが送られると、次のようなフォーマットでメールが届きます。(画面は Gmail のものです。)

下部の「リファラ URL」とは、お問い合わせのページを開く前にアクセスしていたページの情報です。プラグインだとアクセス元を取得することができないので、便利機能として実装したものです。

非同期による高速処理を実現

冒頭でも説明しましたが、このメールフォームの最大の特徴が非同期による処理です。

Ajax で実装することで、全ての処理が1つの画面内で完結するように仕上がっています。メール送信処理は簡単なプログラムなので、送信ボタンを押してから一瞬で処理結果が表示されます。

一般的なメールフォームでは送信完了画面に遷移するものが多く、画面の再読込が発生します。送信してから完了画面を描画するまで、少なく見積もっても数秒は掛かるので、この非同期メールフォームの速さには驚くかもしれません。

では最後に、このメールフォームを利用する上での注意点をお伝えしておきます。

注意点

  • JavaScript が動作する環境が必須になります
  • 迷惑メール対策は実装していません

WordPress から送られる迷惑メールは、プラグインを使ったメールフォームを設置しているサイトに多く見られます。全て同じ仕組みなので、外部から大量に送られやすいのデメリットがあります。

自作のフォームであれば余程のことがない限り、連投で迷惑メールが飛んでくることはありません。ただ、将来的には迷惑メール対策の機能を拡張する必要性はあると考えています。

もし上記のメールフォームを利用して迷惑メールに困るようなことがあれば、何かしら対策を練ろうと思うので、お気軽に「お問い合わせ」もしくは Twitter (@_NJ69_) にご連絡いただければ幸いです。

以上、WordPress でプラグインを利用しない自作メールフォームの紹介でした。

このブログの運営者

NJ

気力・体力勝負なシステム業界のエンジニアを経て、個人事業主として独立。Web サイト運営、動画制作など活動の場を広げています。

このブログでは、困ってたどり着いた人に、分かりやすく答えを提供できるように心掛けています。更新情報は、Twitter や Facebook ページを参照ください。フォローお待ちしています。

Facebook ページ NJ-CLUCKER
このブログが役に立ったら
「いいね!」お願いします

サイト内検索