メールフォーム作成
以下のサイト様からソースコードを一部拝借しています。
- webに生きる人+α - PHPのmb_send_mail()を使った時にgmailだけメールが届かない
- Allied ArchitectsEngineer BlogRSS - PHPでJIS以外の文字を文字化けせずに日本語メールを送る方法
- VeryPosi - PHP応用 コンタクトフォームの作成 入力チェックの追加
3番目のエントリのPHPロジック部分は全然ダメなのですが、サッと作れるデザインとしてはなかなか気に入ったので…w
ソースコード
sendmailに渡す -f
(Return-Path) は適切に指定してください。
<?php
/**
* HTML特殊文字をエスケープする関数
*/
function h($str) {
return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}
/**
* RuntimeExceptionを生成する関数
* http://qiita.com/mpyw/items/6bd99ff62571c02feaa1
*/
function e($msg, Exception &$previous = null) {
return new RuntimeException($msg, 0, $previous);
}
/**
* 例外スタックを配列に変換する関数
* http://qiita.com/mpyw/items/6bd99ff62571c02feaa1
*/
function exception_to_array(Exception $e) {
do {
$msgs[] = $e->getMessage();
} while ($e = $e->getPrevious());
return array_reverse($msgs);
}
/* 変数の初期化 */
foreach (array('name', 'email', 'contents', 'token', 'confirm', 'execute') as $v) {
$$v = trim(filter_input(INPUT_POST, $v));
}
/* セッションの初期化 */
session_name('ContactForm');
@session_start();
if (!isset($_SESSION['token'])) {
$_SESSION['token'] = array();
}
/* 「確認」か「送信」のときのみ実行 */
if ($confirm or $execute) {
try {
// トークンをチェック
if (!isset($_SESSION['token'][$token])) {
throw e('フォームの有効期限が切れています。', $e);
}
// トークンを消費させる
unset($_SESSION['token'][$token]);
// 各項目チェック
if ($name === '') {
$e = e('名前を入力してください。', $e);
}
if ($email === '') {
$e = e('メールアドレスを入力してください。', $e);
} elseif (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$e = e('メールアドレスが不正です。', $e);
}
// 例外がここまでに1つでも発生していればスローする
if (!empty($e)) {
throw $e;
}
// 「送信」のとき
if (
$execute and
!mb_internal_encoding('utf-8') ||
!mail(
'info@example.com',
mb_encode_mimeheader('フォームからの送信', 'ISO-2022-JP-MS'),
mb_convert_encoding($contents, 'ISO-2022-JP-MS'),
implode("\r\n", array(
'Content-Type: text/plain; charset=ISO-2022-JP',
'From: ' . mb_encode_mimeheader($name, 'ISO-2022-JP-MS')
. ' <' . $email . '>',
)),
'-f info@example.com'
)
) {
throw e('メール送信でエラーが発生しました。', $e);
}
} catch (Exception $e) {
// 最初の画面に戻す
$confirm = $execute = '';
}
}
/* 「最初」か「確認」のときのみ実行 */
if (!$execute) {
// 値をダミーにしてトークンをキー部分に生成(最大10個まで保持)
$_SESSION['token'] = array_slice(
array($token = sha1(mt_rand()) => true) + $_SESSION['token'],
0,
10
);
}
// ヘッダー送信
header('Content-Type: application/xhtml+xml; charset=utf-8');
?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="ja">
<head>
<title>Contact Form</title>
<style type="text/css"><![CDATA[
h1 {
color: red;
font-size: 18pt;
}
#contact-form th {
background-color: #9bdbea;
padding: 10px 20px;
}
#contact-form td {
background-color: #f7f7ef;
padding: 10px 20px;
}
#contact-form td input {
width: 400px;
}
#contact-form td textarea {
width: 400px;
}
form {
display: inline;
}
#errmsg {
background-color:#E7D3D6;
border:3px solid #A55952;
color:#944121;
font-size:12px;
margin:10px;
padding:10px;
text-align:left;
width:400px;
}
]]></style>
</head>
<body>
<h1>コンタクトフォーム</h1>
<?php if (!empty($e)): ?>
<div id="errmsg">
<ul>
<?php foreach (exception_to_array($e) as $msg): ?>
<li><?=$msg?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<?php if ($execute): ?>
<p>送信しました。ご意見ありがとうございました。<br /><a href="">戻る</a></p>
<?php elseif ($confirm): ?>
<p>この内容で送信しますか?</p>
<p>
<form action="" method="post">
<table id="contact-form" border="1" cellpadding="0" cellspacing="0">
<tr>
<th>名前(必須)</th>
<td><?=h($name)?></td>
</tr>
<tr>
<th>メールアドレス(必須)</th>
<td><?=h($email)?></td>
</tr>
<tr>
<th>内容</th>
<td><pre><?=
$contents !== '' ?
h($contents) :
'<span style="color:red;">【未入力】</span>'
?></pre></td>
</tr>
<tr>
<th colspan="2">
<input type="hidden" name="name" value="<?=h($name)?>" />
<input type="hidden" name="email" value="<?=h($email)?>" />
<input type="hidden" name="contents" value="<?=h($contents)?>" />
<input type="hidden" name="token" value="<?=h($token)?>" />
<input type="submit" name="execute" value="送信" />
<input type="submit" value="修正" />
</th>
</tr>
</table>
</form>
</p>
<?php else: ?>
<p>
<form action="" method="post">
<table id="contact-form" border="1" cellpadding="0" cellspacing="0">
<tr>
<th>名前(必須)</th>
<td><input type="text" name="name" value="<?=h($name)?>" /></td>
</tr>
<tr>
<th>メールアドレス(必須)</th>
<td><input type="text" name="email" value="<?=h($email)?>" /></td>
</tr>
<tr>
<th>内容</th>
<td><textarea name="contents" rows="10"><?=h($contents)?></textarea></td>
</tr>
<tr>
<th colspan="2"><input type="submit" name="confirm" value="確認" /></th>
</tr>
</table>
<div><input type="hidden" name="token" value="<?=h($token)?>" /></div>
</form>
</p>
<?php endif; ?>
</body>
</html>