PHP
HTML,CSS
CentOS6

お問い合わせフォームをつくる

概要

HTML5とかまったく触ってこなかったズブの素人がPHPとか使って自宅サーバーにお問い合わせフォームを作るまで。

環境

  • サーバーOS:CentOS6(32bit)
  • Webサーバーソフト:Apache
  • 使ったもの:php
  • SMTPサーバー:かりてきたやつ

手順

  1. サーバーの準備
  2. phpのライブラリの調達
  3. htmlとかつくる
  4. sendMail.phpつくる

実践編

サーバーの準備

PHPまわり

PHP使うの初めてなのでPHPの環境から揃えました。
参考にしたのはここです。
Server World

# yum -y install php php-mbstring php-pear 

でPHPのインストール(root権限)

# vi /etc/php.ini 

で設定ファイルを開いたら

php.ini
date.timezone = "Asia/Tokyo"

に書き換え&コメントアウトの解除
Apacheの再起動して終わり。

SELinuxまわり

SELinuxがEnforceになっているとメールが出せない症状があったけど、Disabledはちょっと嫌だなと思ったので少し設定

# setsebool -P httpd_can_sendmail 1

でメール出しても怒られなくなった。

PHPライブラリの調達とか

今回使ったのは

  • class.phpmailer.php
  • class.smtp.php
  • PHPMailerAutoload.php

の3つです。
あとはPHPではないですがjQueryも使いました。

調達

GitHub@ivantcholakov
今回はphpとかhtmlとか置くディレクトリにphpってディレクトリ作ってそこ上記の3つを保存。

HTMLつくる

計画

index.html中にお問い合わせフォームを作る(ここはURLをindex.phpにしたくない)

送信

confirm.phpで確認画面を出して→→(問題なければ)→→mailSend.phpで送信
↓      ↑     
↓まだ編集する↑
↓      ↑
edit.phpで編集画面出す

って感じにしようかと。

index.html内のフォーム

※Bootstrap使ってます。
form.png

こんな感じの見た目に。
コードは↓

index.html
                <form action="confirm.php" method="post" name="Form1">
                    <div class="form-group">
                        <label>お名前 <span class="label label-danger">必須</span></label>
                        <input type="text" class="form-control" placeholder="フォーム太朗" name="name" required>
                        <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
                        <div class="help-block with-errors"></div>
                    </div>
                    <div class="form-group">
                        <label>メールアドレス <span class="label label-danger">必須</span></label>
                        <input type="email" class="form-control" placeholder="xxxxxx@yahoo.co.jp" name="email" required>
                        <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
                        <div class="help-block with-errors"></div>
                    </div>
                    <div class="form-group">
                        <label>住所</label>
                        <input type="text" class="form-control" placeholder="○○県△△市□□町xxxx-yy-z" name="address">
                    </div>
                    <div class="form-group">
                        <label>電話番号</label>
                        <input type="text" class="form-control" placeholder="xxx-yyyy-zzzz" name="phone">
                    </div>
                    <label>件名</label><br>
                    <label class="radio-inline">
                        <input type="radio" name="subjectR" value="checkboxA" onClick="changeDisabled()"> 〇〇のご依頼について
                    </label>
                    <label class="radio-inline">
                        <input type="radio" name="subjectR" value="checkboxB" onClick="changeDisabled()"> △△について
                    </label>
                    <label class="radio-inline">
                        <input type="radio" name="subjectR" value="others" onClick="changeDisabled()"> その他(下記の件名にご記入ください)
                    </label>
                    <div class="form-group" style="margin-top:10px;">
                        <input type="text" class="form-control" placeholder="〇〇について" name="subject" onClick="changeDisabled()">
                    </div>
                    <div class="form-group">
                        <label>お問い合わせ内容 <span class="label label-danger">必須</span></label>
                        <textarea placeholder="お問い合わせ内容" rows="10" class="form-control" name="main" required></textarea>
                <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
                <div class="help-block with-errors"></div>
                    </div>
                    <button type="submit" class="btn btn-warning btn-lg btn-block">送信</button>
                </form>

            <!-- 件名その他を押したときだけテキストボックスをONにする -->
            <script type="text/javascript">
                function changeDisabled() {
                    if ( document.Form1["subjectR"][2].checked ) {
                        document . Form1["subject"] . disabled = false;
                    } else {
                        document . Form1["subject"] . disabled = true;
                    }
                }
                window.onload = changeDisabled;
            </script>

  • 赤く「必須」と書かれている項目は記入せずに送信を押すと「このフィールドは入力必須です」と出ます。
  • メールアドレスの欄はアドレスっぽい文字列以外を入れると怒られます。
  • 件名は三つ目のラジオボタンを押したとき以外はフィールドが使えないようになってます。

上ふたつの処理はinputのところでtype=""を指定するのと、requiredと書くだけなのでとても楽でした。
最後のひとつはjavascriptで処理を書いたのでちょっと面倒(ググったの丸パクリだけど)

確認画面 confirm.php

上記のフォームの必須項目をちゃんと入力して送信を押すとこの画面に移ります
form1.png

コードは↓

confirm.php
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="css/bootstrap.min.css" />
    <title>送信確認フォーム</title>
    <!-- PHP -->
    <?php
        session_start();
        $_SESSION['name'] = $_POST['name'];
        $_SESSION['email'] = $_POST['email'];
        if(empty($_POST['address']))
        {
            $_SESSION['address'] = "記入無し";
        }
        else
        {
            $_SESSION['address'] = $_POST['address'];
        }
        if(empty($_POST['phone']))
        {
            $_SESSION['phone'] = "記入無し";
        }
        else
        {
            $_SESSION['phone'] = $_POST['phone'];
        }
        $value = $_POST['subjectR'];
        if($value=="checkboxA")
        {
            $_SESSION['subject'] = "〇〇について";
        }
        elseif($value=="checkboxB")
        {
            $_SESSION['subject'] = "△△について";
        }
        else
        {
            $_SESSION['subject'] = $_POST['subject'];
        }
        $_SESSION['main'] = $_POST['main'];
    ?>
</head>
<body>
    <div id="style">style</div>
    <div class="container">
        <div class="row">
            <div class="conrtainer left">            
                <div class="col-xs-10 col-xs-offset-1" style="margin-top:30px; margin-bottom:30px;">
                    お問い合わせありがとうございます。<br>
                    この内容で送信いたします。<br>
                    <table class="table" style="table-layout:fixed;">
                        <thead><th style="width:200px;"></th><th></th></thead>
                        <tbody>
                            <tr>
                                <td>[お名前]:</td>
                                <td>
                                    <?php echo $_SESSION['name']; ?>
                                </td>
                            </tr>
                            <tr>
                                <td>[メールアドレス]:</td>
                                <td>
                                    <?php echo $_SESSION['email']; ?>
                                </td>
                            </tr>
                            <tr>
                                <td>[住所]:</td>
                                <td>
                                    <?php echo $_SESSION['address'] ?>
                                </td>
                            </tr>
                            <tr>
                                <td>[電話番号]:</td>
                                <td>
                                    <?php echo $_SESSION['phone'] ?>
                                </td>
                            </tr>
                            <tr>
                                <td>[件名]:</td>
                                <td>
                                    <?php echo $_SESSION['subject'] ?>
                                </td>
                            </tr>
                            <tr>
                                <td>[お問い合わせ内容]:</td>
                                <td>
                                    <?php echo nl2br($_SESSION['main']); ?>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                    <form action="sendMail.php" method="Post">
                        <button type="submit" class="btn btn-success btn-lg btn-block">送信</button>
                    </form>
                    <br>
                    <form action="edit.php" method="Post">
                        <button type="submit" class="btn btn-warning btn-lg btn-block">編集</button>
                    </form>
                </div>  
            </div>
    </div>
</body>
</html>

PHPの大事なところはだいたいヘッダの中に書いてしまってますが、編集や送信で別ページに移っても入力したデータが消えてほしくないのでsessionを使っています。
POSTで送られてきたデータを新たにSESSIONの変数に格納してます。
このとき入力必須ではない住所と電話番号はEMPTY関数を使って検知し、「記入無し」と自動的に入ります。
ラジオボタンで選択できる件名は簡単な条件分岐で日本語の件名が変数に格納されます。

編集画面 edit.php

確認画面から編集画面に移れます。
form2.png
それぞれの変数をvalue=""の中に入れているだけで、特に変なことはしてません。
ハマったのはtextareaはvalueじゃないってことですかね、初心者丸出しでお恥ずかしい。

edit.php
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="css/bootstrap.min.css" />
        <title>お問い合わせフォーム--編集</title>
    <!-- PHP -->
    <?php
        session_start();
        $name = $_SESSION['name'];
        $email = $_SESSION['email'];
        $address = $_SESSION['address'];
        $phone = $_SESSION['phone'];
        $subject = $_SESSION['subject'];
        $main = $_SESSION['main'];
    ?>
</head>
<body>
    <div class="container">
            <div class="conrtainer left">            
                <div class="col-xs-10 col-xs-offset-1" style="margin-top:30px; margin-bottom:30px;">
                    ブラウザの[戻る]は使わないでください。<br>
            <div class="col-xs-10 col-xs-offset-1" style="margin-top:30px; margin-bottom:30px;">
                <form action="confirm.php" method="post">
                    <div class="form-group">
                        <label>お名前 <span class="label label-danger">必須</span></label>
                        <input type="text" class="form-control" value="<?php echo $name; ?>" name="name" data-required-error="名前を入れてください" required>
                <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
                <div class="help-block with-errors"></div>
                    </div>
                    <div class="form-group">
                        <label>メールアドレス <span class="label label-danger">必須</span></label>
                        <input type="email" class="form-control" value="<?php echo $email; ?>" name="email" required>
                <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
                <div class="help-block with-errors"></div>
                    </div>
                    <div class="form-group">
                        <label>住所</label>
                        <input type="text" class="form-control" value="<?php echo $address; ?>" name="address">
                    </div>
                    <div class="form-group">
                        <label>電話番号</label>
                        <input type="text" class="form-control" value="<?php echo $phone; ?>" name="phone">
                    </div>
                    <div class="form-group">
                        <label>件名</label>
                        <input type="text" class="form-control" value="<?php echo $subject; ?>" name="subject">
                    </div>
                    <div class="form-group">
                        <label>お問い合わせ内容 <span class="label label-danger">必須</span></label>
                        <textarea rows="10" class="form-control" name="main" required><?php echo $main; ?></textarea>
                    <span class="glyphicon form-control-feedback" aria-hidden="true"></span>
                    <div class="help-block with-errors"></div>
                    </div>
                    <button type="submit" class="btn btn-warning btn-lg btn-block">確認</button>
                </form>
            </div>
        </div>
    </div>
</body>
</html>

SESSIONを使うページではすべてのページでsession_start();を言わないといけないらしい。
ここの確認を押すとさっきのconfirmに修正された値が渡される。

sendMail.phpつくる

ぶっちゃけここが一番しんどかったです。
phpの環境ってよくわかってなくて、サーバー側で詰まってるのか、phpが詰まってるのか、その辺が全然でした。
いろいろ試したんですが「PHPMailerを使ってGmailのSMTP経由でメールを送信する際にSMTP connect() failed.と出て困った」のやり方でできました。
ただし、GMailにはどうしても届かないので送り先はGMail以外のものにしてください。

sendMail.php
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="refresh" content="0; URL=index.html"/>
        <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    </head>

    <body>
        <div class="mailform">
            <?php
                session_start();
                require_once ( 'php/PHPMailerAutoload.php' );
                $subject = "お問い合わせ";
                $body = '[お名前]'."\n".$_SESSION['name']."\n"
                        .'[メールアドレス]'."\n".$_SESSION['email']."\n"
                        .'[住所]'."\n".$_SESSION['address']."\n"
                        .'[電話番号]'."\n".$_SESSION['phone']."\n"
                        .'[件名]'."\n".$_SESSION['subject']."\n"
                        .'[本文]'."\n".$_SESSION['main']."\n";
                $fromname = "メーラーに表示したい名前";
                $fromaddress = "送り元のアドレス";
                $smtp_user = "SMTPサーバーのユーザー名";
                $smtp_password = "SMTPサーバーのパスワード";
                $to = "送り先";

                $mail = new PHPMailer();
                $mail->IsSMTP();
                $mail->SMTPDebug = 1; // debugging: 1 = errors and messages, 2 = messages only
                $mail->SMTPAuth = true;
                $mail->CharSet = 'utf-8';
                $mail->SMTPSecure = 'ssl';
                $mail->Host = "SMTPサーバー";
                $mail->Port = 465;
                $mail->IsHTML(false);
                $mail->Username = $smtp_user;
                $mail->Password = $smtp_password; 
                $mail->SetFrom($smtp_user);
                $mail->From     = $fromaddress;
                $mail->Subject = $subject;
                $mail->Body = $body;
                $mail->AddAddress($to);

                if( !$mail -> Send() ){
                    $message  = "Message was not sent<br/ >";
                    $message .= "Mailer Error: " . $mailer->ErrorInfo;
                } else {
                    $message  = "Message has been sent";
                }

                echo $message;

                ?>
            <br>
            <input type="button" class="btn btn-success" value="自動的に戻らない場合は押してください。" onClick="location.href='index.html'">
        </div>
    </body>
</html>

メタタグのところはリダイレクトで勝手にindex.htmlに戻るようになってます。
件名はフォームから送られてきたことが分かるようなものにしてますが、

$SUBJECT = $_SESSION['subject']

とかにしてもいいと思います。
設定しなければならないのは

  • $smtp_user
  • $smtp_password
  • $mail -> Host = "";
  • $mail -> Port = ;

あたりですね。
これらはSMTPサーバーの仕様のところに書いてあるものです。
今回は個人情報なのでSSLで暗号化してるのでポートは465使いました。
(自宅のルーターのポート開放は不要)

これで送れないときはリダイレクトを消してエラーメッセージ読むか、サーバー側のlog読んでみてください。
たぶん解決のヒントがあると思います(めっちゃお世話になった)。

さいごに

はじめてのphp、はじめてのjQuery、はじめてのHTML5、はじめてのBootstrapと初めて尽くしだったのでほんとうにいい勉強になりました。
セキュリティとかがんばって勉強したいと思いますので、ここはこうしたほうがいい、とかそういうコメントお待ちしております。よしなに。