phpな休日 BBS sitemap
1. メールを送る

一行掲示板のところで触れましたが、PHPでメールを送るのはとても簡単です。
mb_send_mail ("送信先アドレス", "件名", "内容");
の一行であとはmb_send_mail関数がうまくやってくれます。(サーバー側で send_mail使用可が前提)
メールフォームの必要項目は [名前(name)]、[メールアドレス(email)]、[件名(title)]、[本文(comment)] とし、他に [送信日時(time)] と [送信者ホスト情報(iphost)] を取得しておきます。
2重送信を防止するため、最新1件分のログをサーバーにデータとして残しています。その際データに残す comment は [改行] を <br> に変換しておく必要があります。($ccomentとしました)
ログファイル名は mail.cgi です。ブラウザからログファイルにアクセスしても読めないように拡張子は .cgi にしてください。

<?php
mb_language("ja");
mb_internal_encoding("UTF-8");
if (($_POST["name"] != "") or ($_POST["comment"] != "")) { //もしPOSTに [name] か [comment] があれば
if (isset($_POST["name"])) { //もしPOSTに [name] があれば
$name = $_POST["name"]; //POSTのデータを変数$nameに格納
if( get_magic_quotes_gpc() ) { $name = stripslashes("$name"); } //クォートをエスケープする
$name = htmlspecialchars ($name); //HTMLタグ禁止
$name = mb_strimwidth ($name, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["email"])) { //もしPOSTに [email] があれば
$email = $_POST["email"]; //POSTのデータを変数$emailに格納
if( get_magic_quotes_gpc() ) { $email = stripslashes("$email"); } //クォートをエスケープする
$email = htmlspecialchars ($email); //HTMLタグ禁止
$email = mb_strimwidth ($email, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["title"])) { //もしPOSTに [title] があれば
$title = $_POST["title"]; //POSTのデータを変数$titleに格納
if( get_magic_quotes_gpc() ) { $title = stripslashes("$title"); } //クォートをエスケープする
$title = htmlspecialchars ($title); //HTMLタグ禁止
$title = mb_strimwidth ($title, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["comment"])) { //もしPOSTに [comment] があれば
$comment = $_POST["comment"]; //POSTのデータを変数$commentに格納
if( get_magic_quotes_gpc() ) { $comment = stripslashes("$comment"); } //クォートをエスケープする
$comment = htmlspecialchars ($comment); //HTMLタグ禁止
$comment = mb_strimwidth ($comment, 0, 10000, "", "UTF-8"); //長いデータを10000バイトでカット
$ccomment = str_replace("¥r¥n", "¥r", $comment); //Windowsの改行コードを置き換え
$ccomment = str_replace("¥r", "¥n", $ccomment); //Machintoshの改行コードを置き換え
$ccomment = str_replace("¥n", "<br>", $ccomment); //¥nを<br>に置き換え
}
$data = fopen ("./mail.cgi","r"); //ファイルを読みこみ専用でオープン
$bdata = fgets ($data); //1行読み込む
list($bname,$bemail,$btitle,$bcomment,$btime,$biphost) = explode("<>",$bdata); //変数に変換
fclose($data); //ファイルを閉じる
if (($bname != $name) or ($bcomment != $ccomment)){ // name か ccomment が違っていれば
$time = date("Y/n/j G:i"); //日時の取得
$ip = getenv("REMOTE_ADDR"); //IPアドレス取得
$host = gethostbyaddr(getenv("REMOTE_ADDR")); //HOST取得
$iphost = ($host . "/" . $ip);
mb_send_mail ("hoge@hoge.net", "$title", "$name 様¥n$email¥n$comment¥n$time¥n$iphost¥n");
$topwrite = "$name<>$email<>$title<>$ccomment<>$time<>$iphost<>¥n"; //新しく記録するデータを <> で区切って整形
$log = fopen ("./mail.cgi","w"); //書き込み用モードでデータを開く(データは空になる)
flock ($log, LOCK_EX); //ファイルロック開始
fputs ($log,$topwrite); //書き込み処理
flock ($log, LOCK_UN); //ファイルロック解除
fclose ($log); //ファイルを閉じる
}
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>mail_form</title>
</head>
<body>
<form method="POST" action="mailform.php">
お名前<br>
<input type="text" name="name" size="40"><br>
E-mail<br>
<input type="text" name="email" size="40"><br>
件名<br>
<input type="text" name="title" size="40"><br>
コメント<br>
<textarea name="comment" cols="40" rows="4"></textarea><br>
<input type="submit" value="送信">
</form>
</body>
</html>

サブウインドウで実行 //送信部分をコメントアウトしてありますので実際にはメール送信されません。
2. メールを送ったあとメッセージを表示

メール送信は出来たのですが、送信者の立場に立つと送信後の反応が何もないので心配になってしまうかもしれません。何かメッセージを出すようにしましょう。
赤文字で記します。

<?php
mb_language("ja");
mb_internal_encoding("UTF-8");
if (($_POST["name"] != "") or ($_POST["comment"] != "")) { //もしPOSTに [name] か [comment] があれば
if (isset($_POST["name"])) { //もしPOSTに [name] があれば
$name = $_POST["name"]; //POSTのデータを変数$nameに格納
if( get_magic_quotes_gpc() ) { $name = stripslashes("$name"); } //クォートをエスケープする
$name = htmlspecialchars ($name); //HTMLタグ禁止
$name = mb_strimwidth ($name, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["email"])) { //もしPOSTに [email] があれば
$email = $_POST["email"]; //POSTのデータを変数$emailに格納
if( get_magic_quotes_gpc() ) { $email = stripslashes("$email"); } //クォートをエスケープする
$email = htmlspecialchars ($email); //HTMLタグ禁止
$email = mb_strimwidth ($email, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["title"])) { //もしPOSTに [title] があれば
$title = $_POST["title"]; //POSTのデータを変数$titleに格納
if( get_magic_quotes_gpc() ) { $title = stripslashes("$title"); } //クォートをエスケープする
$title = htmlspecialchars ($title); //HTMLタグ禁止
$title = mb_strimwidth ($title, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["comment"])) { //もしPOSTに [comment] があれば
$comment = $_POST["comment"]; //POSTのデータを変数$commentに格納
if( get_magic_quotes_gpc() ) { $comment = stripslashes("$comment"); } //クォートをエスケープする
$comment = htmlspecialchars ($comment); //HTMLタグ禁止
$comment = mb_strimwidth ($comment, 0, 10000, "", "UTF-8"); //長いデータを10000バイトでカット
$ccomment = str_replace("¥r¥n", "¥r", $comment); //Windowsの改行コードを置き換え
$ccomment = str_replace("¥r", "¥n", $ccomment); //Machintoshの改行コードを置き換え
$ccomment = str_replace("¥n", "<br>", $ccomment); //¥nを<br>に置き換え
}
$data = fopen ("./mail.cgi","r"); //ファイルを読みこみ専用でオープン
$bdata = fgets ($data); //1行読み込む
list($bname,$bemail,$btitle,$bcomment,$btime,$biphost) = explode("<>",$bdata); //変数に変換
fclose($data); //ファイルを閉じる
if (($bname != $name) or ($bcomment != $ccomment)){ // name か ccomment が違っていれば
$time = date("Y/n/j G:i"); //日時の取得
$ip = getenv("REMOTE_ADDR"); //IPアドレス取得
$host = gethostbyaddr(getenv("REMOTE_ADDR")); //HOST取得
$iphost = ($host . "/" . $ip);
mb_send_mail ("hoge@hoge.net", "$title", "$name 様¥n$email¥n$comment¥n$time¥n$iphost¥n");
$message = "ありがとうございます。送信しました。";
$topwrite = "$name<>$email<>$title<>$ccomment<>$time<>$iphost<>¥n"; //新しく記録するデータを <> で区切って整形
$log = fopen ("./mail.cgi","w"); //書き込み用モードでデータを開く(データは空になる)
flock ($log, LOCK_EX); //ファイルロック開始
fputs ($log,$topwrite); //書き込み処理
flock ($log, LOCK_UN); //ファイルロック解除
fclose ($log); //ファイルを閉じる
}
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>mail_form</title>
</head>
<body>
<?php
if (isset($message)) {
print $message;
}
?>
<form method="POST" action="mailform.php">
お名前<br>
<input type="text" name="name" size="40"><br>
E-mail<br>
<input type="text" name="email" size="40"><br>
件名<br>
<input type="text" name="title" size="40"><br>
コメント<br>
<textarea name="comment" cols="40" rows="4"></textarea><br>
<input type="submit" value="送信">
</form>
</body>
</html>

メール送信(mb_send_mail)のあとに変数 $message をセットしておきます。
ページ表示時、変数 $message が存在すれば表示します。

サブウインドウで実行 //送信部分をコメントアウトしてありますので実際にはメール送信されません。
3. メールを送るまえに確認画面を表示

FORMに入力してから送信処理までの間に確認画面を表示するようにします。
イメージは左図。
FORMで
<input type="submit" value="送信">
としていたところを
<input type="submit" name="conf" value="確認画面へ">
に変更します。
スクリプトが $_POST["conf"] を受け取ったら処理を分岐するようにします。

<?php
mb_language("ja");
mb_internal_encoding("UTF-8");
if (($_POST["name"] != "") or ($_POST["comment"] != "")) { //もしPOSTに [name] か [comment] があれば
if (isset($_POST["name"])) { //もしPOSTに [name] があれば
$name = $_POST["name"]; //POSTのデータを変数$nameに格納
if( get_magic_quotes_gpc() ) { $name = stripslashes("$name"); } //クォートをエスケープする
$name = htmlspecialchars ($name); //HTMLタグ禁止
$name = mb_strimwidth ($name, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["email"])) { //もしPOSTに [email] があれば
$email = $_POST["email"]; //POSTのデータを変数$emailに格納
if( get_magic_quotes_gpc() ) { $email = stripslashes("$email"); } //クォートをエスケープする
$email = htmlspecialchars ($email); //HTMLタグ禁止
$email = mb_strimwidth ($email, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["title"])) { //もしPOSTに [title] があれば
$title = $_POST["title"]; //POSTのデータを変数$titleに格納
if( get_magic_quotes_gpc() ) { $title = stripslashes("$title"); } //クォートをエスケープする
$title = htmlspecialchars ($title); //HTMLタグ禁止
$title = mb_strimwidth ($title, 0, 40, "", "UTF-8"); //長いデータを40バイトでカット
}
if (isset($_POST["comment"])) { //もしPOSTに [comment] があれば
$comment = $_POST["comment"]; //POSTのデータを変数$commentに格納
if( get_magic_quotes_gpc() ) { $comment = stripslashes("$comment"); } //クォートをエスケープする
$comment = htmlspecialchars ($comment); //HTMLタグ禁止
$comment = mb_strimwidth ($comment, 0, 10000, "", "UTF-8"); //長いデータを10000バイトでカット
$ccomment = str_replace("¥r¥n", "¥r", $comment); //Windowsの改行コードを置き換え
$ccomment = str_replace("¥r", "¥n", $ccomment); //Machintoshの改行コードを置き換え
$ccomment = str_replace("¥n", "<br>", $ccomment); //¥nを<br>に置き換え
}
$data = fopen ("./mail.cgi","r"); //ファイルを読みこみ専用でオープン
$bdata = fgets ($data); //1行読み込む
list($bname,$bemail,$btitle,$bcomment,$btime,$biphost) = explode("<>",$bdata); //変数に変換
fclose($data); //ファイルを閉じる
if (($bname != $name) or ($bcomment != $ccomment)){ // name か ccomment が違っていれば
if (!$_POST["conf"]) { //もしPOSTに [conf] がなければ
$time = date("Y/n/j G:i"); //日時の取得
$ip = getenv("REMOTE_ADDR"); //IPアドレス取得
$host = gethostbyaddr(getenv("REMOTE_ADDR")); //HOST取得
$iphost = ($host . "/" . $ip);
mb_send_mail ("hoge@hoge.net", "$title", "$name 様¥n$email¥n$comment¥n$time¥n$iphost¥n");
$message = "ありがとうございます。送信しました。";
$topwrite = "$name<>$email<>$title<>$ccomment<>$time<>$iphost<>¥n"; //新しく記録するデータを <> で区切って整形
$log = fopen ("./mail.cgi","w"); //書き込み用モードでデータを開く(データは空になる)
flock ($log, LOCK_EX); //ファイルロック開始
fputs ($log,$topwrite); //書き込み処理
flock ($log, LOCK_UN); //ファイルロック解除
fclose ($log); //ファイルを閉じる
}
}
}
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>mail_form</title>
</head>
<body>
<?php
if (isset($_POST["conf"])) { //もしPOSTに [conf] があれば
print "以下の内容で送信してよろしいですか?<br>¥n";
print "お名前:" . $name . "<br>¥n";
print "メールアドレス:" . $email . "<br>¥n";
print "件名:" . $title . "<br>¥n";
print "本文:<br>" . $ccomment . "<br>¥n";
?>
<form method="POST" action="mailform.php">
<input type="hidden" name="name" value="<?php print $name; ?>">
<input type="hidden" name="email" value="<?php print $email; ?>">
<input type="hidden" name="title" value="<?php print $title; ?>">
<input type="hidden" name="comment" value="<?php print $comment; ?>">
<input type="submit" value="この内容で送信">
</form>
<br>
<a href="javascript:history.back()">戻って修正する</a>
<?php
}
else {
if (isset($message)) {
print $message;
}
?>
<form method="POST" action="mailform.php">
お名前<br>
<input type="text" name="name" size="40"><br>
E-mail<br>
<input type="text" name="email" size="40"><br>
件名<br>
<input type="text" name="title" size="40"><br>
コメント<br>
<textarea name="comment" cols="40" rows="4"></textarea><br>
<input type="submit" name="conf" value="確認画面へ">
</form>
<?php
}
?>
</body>
</html>

確認画面でPOSTから受け取ったデータを本送信する時にもう一度POSTする必要があります。その場合変数に入っているデータを再度FORMの <input> タグに入れて送信するのですが、ユーザーからは <input> のフォームは見える必要がないので hidden 属性でPOST に渡すようにします。

サブウインドウで実行 //送信部分をコメントアウトしてありますので実際にはメール送信されません。

うまくスクリプトが書けない方、すぐには環境(エディタなど)が整わない方、とにかく設置して動作を見たい方のために こちら からzip形式をダウンロードできるようにしました。

2014.2.4 last edit

Produced by haku