前回のエントリで問い合わせフォームのトラブルについて書いた。トラブルフリーな問い合わせフォームは無いけれど、トラブルの影響を最小限に食い止めるための方策はいろいろある。すなわち「問い合わせをもらっていたのに知らなかった」という状況を避ける対処法。僕が気をつけているのは以下のこと。
1. mb_send_mail()の戻り値は必ずチェック
mb_send_mail()はmail()のラッパクラスで、mail()はphp.iniでパス指定されたsendmailコマンドを呼んでいる。sendmailコマンドがリクエストを正しく受け入れると正常ステータスを返すのだけど、実際にメールを送信するのはMTAの役割なので、メールが送られたかどうかをステータスから判断することはできない。だけど、少なくともリクエストは正しく受け入れられないとメールは送られないので、関数の戻り値は必ずチェックしてエラーはユーザに通知する。ユーザに「エラーで送られなかったんだ」と知らしめるために。
2. メール送り先は複数メールアドレスで、異なるドメインも含めて。
受信メールサーバーの不具合や、メール受信者のミスなどを想定し、メールの控えを複数のメールアドレスに送信しておく。全てのメールアドレスが同じドメインだとサーバー不具合で全不通になるので、異なるドメインのメールアドレスも混ぜておく。たとえばGmailとか。
3. バウンスメールを喪失しないようにenvelop senderを必ず指定。
受信メールサーバーの不具合などでメールがバウンスしてきたときに確実に通知を受け取れるように、sendmailコマンドの -f オプションを使ってenvelop senderを必ず指定する。もし指定しないのなら、どのメールアドレスがenvelop senderになるのかホスティングプロバイダのデフォルト設定を確認した上で、そのメールアドレスへの着信を常時チェックするようにする。
4. フォーム投稿をサーバー上のログファイルに記録して頻繁に目を通す。
メールは信頼できないものと割り切って、全ての投稿をサーバー上のログファイルに欠かさず記録する。たとえ不具合によりメールが一切機能しなくても、ログを見れば問い合わせがあったことと問い合わせ内容を知ることができる。ログファイルはウェブサーバーから見れないところに置くこと、破損しないように排他制御を行うこと、確実に書き込むために書き込みエラー時にはリトライを行うこと、そして必ず頻繁に管理者が目を通すこと、など基本的な点は遵守すること。僕は管理しているサイトのアクセスログを毎日朝一で閲覧するので、そのときにこのログにも必ず目を通すようにしている。
スクリプト例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
<?php // Contact form script define('MAIL_TO', 'yyyy@example.com'); define('BCC', 'zzzz@example.com,abc@sample.com'); define('MAIL_SUBJ', 'Site ABC contact'); define('RETURN_PATH', 'xxxx@example.com'); define('LOG_FILE', '/xxxx/xxxx/xxxx/contact.log'); function sanitize($data) { $charset = 'UTF-8'; $original_charset = 'auto'; foreach ($data as $key => $value) { // Encode the text. mb_internal_encoding($charset); $value = mb_convert_encoding($value, $charset, $original_charset); // Remove HTML tags. $value = strip_tags($value); // Alphanumrcic:hankaku, blank:hankaku, Katakana:zenkaku. $value = mb_convert_kana($value, "asK", $charset); // Remove the leading/tailing spaces. $value = trim($value); $data[$key] = $value; } return $data; } function logging($name, $email, $message, $result) { $ip = @$_SERVER['REMOTE_ADDR']; if ($ip) { $remoteHost = gethostbyaddr($ip); } else { $remoteHost = $ip; } date_default_timezone_set("America/Los_Angeles"); $data = "Date: " . date('Y/m/d H:i:s T') . "\n" . "Host: " . $remoteHost . "\n" . "Name: " . $name . "\n" . "Email: " . $email . "\n" . "Result: " . $result . "\n" . $message . "\n-----\n"; $file = LOG_FILE; $fh = fopen($file, 'a'); for ($i = 0; $i < 5; $i++) { // retry loop if (flock($fh, LOCK_EX)) { fwrite($fh, $data); fflush($fh); flock($fh, LOCK_UN); break; // success } sleep(1); // wait small period } fclose($fh); // TODO: notify if the logging failed } $thanks = false; $errors = ''; $msgs = array(); $msgs['w_name'] = 'Please enter your name.'; $msgs['w_email'] = 'Please enter your email.'; $msgs['w_email2'] = 'Please enter a valid email.'; $msgs['w_message'] = 'Please enter your message'; $msgs['failed'] = 'Sending message failed.'; if ($_POST['submit']) { $_POST = sanitize($_POST); if (!isset($_POST['name']) || $_POST['name'] == '') $errors = $msgs['w_name'] . '<br />'; if (!isset($_POST['email']) || $_POST['email'] == '') $errors = $msgs['w_email'] . '<br />'; if (!isset($_POST['message']) || $_POST['message'] == '') $errors = $msg['w_message']; if ($errors == '') { mb_language("ja"); $name = $_POST['name']; $email = $_POST['email']; $message = $_POST['message']; $to = MAIL_TO; $subject = MAIL_SUBJ; $body = $message . "\n"; $subject = mb_convert_encoding($subject, "ISO-2022-JP", "AUTO"); $subject = mb_encode_mimeheader($subject); $headers = "MIME-Version: 1.0 \n" ; $headers .= "From: " . mb_encode_mimeheader(mb_convert_encoding($name, "ISO-2022-JP", "AUTO")) . " <".$email."> \n"; $headers .= "Bcc: " . BCC . "\n"; $headers .= "Reply-To: " . mb_encode_mimeheader(mb_convert_encoding($name, "ISO-2022-JP", "AUTO")) . " <".$email."> \n"; $parameters = "-f " . RETURN_PATH; if (mb_send_mail($to, $subject, $body, $headers, $parameters)) { $thanks = true; } else { $errors = $msgs['failed']; } logging($name, $email, $message, ($thanks ? "Success" : "Failed")); } } ?> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <link href="style.css" rel="stylesheet" media="all" type="text/css" /> </head> <body> <?php if ($thanks) { ?> <div align="center">Thank you for your message. We wll get back to you ASAP.</div> <?php } else { ?> <!-- Validation script --> <script Language="JavaScript"> <!-- function Validation(theForm) { if (theForm.name.value === "") { alert("<?php echo $msgs['w_name']; ?>"); theForm.name.focus(); return false; } if (theForm.email.value === "") { alert("<?php echo $msgs['w_email']; ?>"); theForm.email.focus(); return false; } if ((theForm.email.value.indexOf('@', 0) === -1) || (theForm.email.value.length < 5)) { alert("<?php echo $msgs['w_name2']; ?>"); theForm.email.focus(); return false; } if (theForm.message.value === "") { alert("<?php echo $msgs['w_message']; ?>"); theForm.message.focus(); return false; } return true; } //--> </script> <div align="center">Please feel free to contact us!</div> <!-- Error Message --> <?php if ($errors != '') echo '<p>'.$errors.'</p>'; ?> <!--- Form ---> <form name="form1" method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" onSubmit="return Validation(this);"> <fieldset> <label>Your name:</label> <input type="text" name="name" size="20" value="<?php echo $_POST['name']; ?>" /><br /> <label>E-mail address:</label> <input type="text" name="email" size="20" value="<?php echo $_POST['email']; ?>" /><br /> <label>Message:</label> <textarea name="message" cols="25" rows="15"><?php echo $_POST['message']; ?></textarea> <br /> <input name="submit" value="Send!" type="submit" /> </fieldset> </form> <?php } ?> </body> </html> |