お問合わせフォームをPHPで実装してみた!(3)

機能紹介

こんにちは,レッドインパルスアルバイターの秦です.

前回までの記事で自動送信メールと入力値の引継ぎを実装しました.これにより,お問い合わせフォームの基本的機能は完成しました.このままでも使えないことはないのですが,送られたメールがスパムとして判定され迷惑メールフォルダに入れられてしまうなど,不便な部分がまだあります.なので,その他の機能として更にお問い合わせフォームを便利にするための機能を今回は紹介していこうと思います.具体的な機能としては以下の通りです.

  • formタグでの遷移防止対策
  • 正規表現(エラーチェック)
  • 多重送信防止対策
  • 迷惑メールボックスに送られないための対策

 

formタグでの遷移防止対策

formタグは昨日として元々勝手にページ遷移するように出来ています.この機能は時としてとても不便に感じることがあります.

例えば,PraginのHPではお問い合わせフォームがページの一番下にあります.なので,CheckやBack, Sendなどのボタンを押した際にページが遷移されページのトップが表示されます.これでは,記入内容を確認するためにボタンを押した後や間違いを直すためにBackを押した後,一々ページ上部から下部までスクロールする必要があります.

この状態だとUIとして最悪です.なので,ボタンを押してもページの上部に移動することなくお問い合わせの部分のみが変わる仕様にする必要があります.今回この問題を解決するために私は色々とググってみました.その結果 JS のライブラリでなんとかなるという記事がいくつか出てきました.しかし端から試したところ,全てうまく動きませんでした.私のコードの書き方が問題なのかそれらの記事が今では使えないのか分かりませんが,がっかりしました.

だからと言って諦めるわけではなく踏ん張ったところ応急処置として?ですが,なんとか submit を押しても画面が遷移しない(正確には遷移している)使用ができました.それは,formタグに遷移後表示させたい箇所の ID を actionに追加するのみです.皆さんのコードにはすでに以下のコードが入力フォームの formタグのところに追加されていると思います.

<form id="form" method="post" action="#contact">

action=”ID名”を追加することで form タグ内の submit を押した際の画面遷移で指定したIDのある位置まで移動することが出来るのです.試しに遷移させてみると以下の画像のようにURLに/#ID名(ここでは/#contact)が追加されると思います.SLL化してあるサイトでも問題なく機能し,画面遷移後もSSLは機能しますので心配しないでください.

 

正規表現(エラーチェック)

正規表現では,入力値に記入漏れが無いかのチェックや入力値が正しい値かどうかなどをチェックする機能です.

例えば,メールアドレス欄にメールアドレスではなく名前やランダムな文字列を入力された場合に警告が出てきて,確認画面に移動できなくなります.他にも,スクリプト言語を入れられた際他のページに遷移させられたり,予期せぬ動作が起きたりします.なので,URLやコードも全て警告の出るようにします.以下の画像は Pragin のHPの動作結果です.

 

page_flag = 1

まずは,最初の記事で追加した

if( !empty($_POST['btn_confirm'])) {
  $page_flag = 1; 
}

を以下のコードに書き換えてください.

if( !empty($_POST['btn_confirm'])) {

    //エラーチェック
    $error = validation($_POST);
    if( empty($error) ) {
        $page_flag = 1;
    }
    
}

上記のコードでは,error変数が空の時(エラーが無い時)にのみ確認ページに移動し,error変数に何か入っている場合(エラーがある場合)はエラー表示をするというものです.エラー判定のコードは次の項目です.

 

エラー判定コード

初めに,変数の初期化に以下のコードを追加してください.

$error = array();

次に,

else {
    $page_flag = 0;
}

の下に以下のコードを追加してください.

function validation($data) {

    $error = array();
    $check = array();

    // 氏名のエラー判定
    if ( empty($data['name']) ) {
        $error[] = " 氏名を記入してください";
    } elseif ( 30 < mb_strlen($data['name']) ) {
        $error[] = " 氏名を記入してください";
    }
    
    // 学校名のエラー判定
    if ( empty($data['college']) ) {
        $error[] = " 学校名を記入してください";
    } elseif ( 50 < mb_strlen($data['college']) ) {
        $error[] = " 学校名を記入してください";
    }
    
    // メールアドレスのエラー判定
    //メールアドレスの@前後をcheck配列に格納(check[1]がドメイン部分)
    $check = explode('@',$data['email']);
    if ( empty($data['email']) ) {
        $error[] = " メールアドレスを記入してください";
    } elseif ( !preg_match( '/^[0-9a-z_.\/?-]+@([0-9a-z-]+\.)+[0-9a-z-]+$/', $data['email']) ) {
        $error[] = " 正しいメールアドレスを記入してください";
    //ドメイン部分が有効か判定
    } elseif (!(checkdnsrr($check[1],'A')) ) {
        $error[] = " 有効なドメインか確認してください";
    } elseif ( 50 < mb_strlen($data['email']) ) {
        $error[] = " 正しいメールアドレスを記入してください";
    }
    
    // メッセージのエラー判定
    if ( empty($data['message']) ) {
        $error[] = " メッセージを記入してください";
    } elseif ( preg_match( '/http|https/', $data['message']) ) {
        $error[] = " メッセージにURLの貼りつけは禁止しています";
    } elseif ( preg_match( '/<(".*?"|\'.*?\'|[^\'"])*?>/', $data['message']) ) {
        $error[] = " メッセージにHTMLの貼りつけは禁止しています";
    } elseif ( preg_match( '/^[  \r\n\t]*$/', $data['message']) ) {
        $error[] = " メッセージを記入してください";
    } elseif ( 1600 < mb_strlen($data[ 'message']) ) {
        $error[]=" 1600字以上は記入できません" ; 
    } return $error;
}

上記の$error[] = “警告文”;はそれぞれの警告文になります.未記入をはじくには if 文で指定の name 属性の項目が空の時(記入されていない時)に警告文を表示するようにします.文字数制限は 文字数 < mb_strlen($data[‘name属性’]) とすることで,指定の文字数以上記入すると警告文が表示されるようになります.

指定の文字をはじきたい場合は preg_match(‘指定の文字’, $data[‘name属性’]) とすることで,指定の文字を記入した際に警告文を表示します.サニタイズでコードを書かれた際に警告文を表示することも可能ですが,これをやると半角文字が入力された時点で(PraginやYahooなど)警告文を表示してしまいました.なので,Praginではサニタイズではなく文字を指定することでコードやURLをはじいています.

メールアドレスが有効かどうかは,@前後の形式が正しいかどうかやドメインが有効かどうかで警告を出すかを判定します.もし,詳しく知りたい方は書かれた関数についてググってみてください.

 

多重送信防止対策

多重送信防止ではまずエラーチェックの $page_flag = 1; の下に以下のコードを追加してください.

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

また,$page_flag = 2; の下に以下のコードを追加してください.

session_start();
    if($_SESSION['page']===true){
        
        //セッションの削除
        unset($_SESION['page']);

更に,$page_flag = 0; の } の後ろにもう一つ } を追加してください.これで else {$page_flag = 0;} も elseif( !empty($_POST[‘btn_submit’])) {}に囲まれました.

これらのコードを追加することで,$_SESSION[‘page’] が true の時のみ送信が可能になり,それ以外は実行できなくなります.

 

迷惑メールボックスに送られないための対策

メールの送信元の情報を指定しておかないと,信頼性が無いとみなされスパムや迷惑メールに分類されてしまう可能性があります.ヘッダー情報のコードを全て以下のコードに書き換えてください.

//言語と文字コードの使用宣言
        mb_language("ja");
        mb_internal_encoding("UTF-8");
        
        //送信元
        $from = "送信元";
        
        //送信元メールアドレス
        $from_mail = "送信元メールアドレス";
        
        //送信者名
        $from_name = "送信者名";

        //ヘッダー情報を設定
        $header .= "MIME-Version: 1.0 \r\n";
        $header .= "From: " . $from ."\r\n";
        $header .= "Reply-To: " . $from_mail ."\r\n";
        $header .= "Content-Type: text/plain \r\n";
        $header .= "Return-Path: " . $from_mail ."\r\n";
        $header .= "Sender: " . $from ."\r\n";
        $header .= "Organization: " . $from_name ."\r\n";
        $header .= "X-Sender: " . $from_mail ."\r\n";
        $header .= "X-Priority: 3 \n";

ヘッダー情報の説明を以下に示します.

  • From: 送信者の名前(組織名)とメールアドレス
  • Reply-To: 受信者に表示される返信用メールアドレス
  • Content-Type: メール形式
  • Return-Path: 送信元メールアドレスが受け取れない時,通知の行くメールアドレス
  • Sender: 送信者の名前(組織名)とメールアドレス
  • Organization: 送信者名(組織名)
  • X-Sender: 送信者のメールアドレス
  • X-Priority: メールの重要度

最後の二つは一部のメーラーのみが参照するので,必須ではありません.

また,送信するサイトとメールアドレスのドメインが一致しないとスパムや迷惑メールとして判定される可能性があるので注意しましょう.

 

まとめ

これでPHPでのお問い合わせフォームの実装は終了です.

初めてのPHPによる実装だったので,もし間違い等があった場合はPraginまで直接ご連絡いただけると幸いです.